Removed Floodlight devicemanager, topology, routing and forwarding modules
Change-Id: Icbdecb2f7c84bcb450ee95177d82ae9c82a3f163
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDevice.java b/src/main/java/net/floodlightcontroller/devicemanager/IDevice.java
deleted file mode 100644
index 95969f8..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDevice.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
-* Copyright 2011,2012 Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager;
-
-import java.util.Date;
-
-
-/**
- * Represents an independent device on the network. A device consists of a
- * set of entities, and all the information known about a given device comes
- * only from merging all associated entities for that device.
- * @author readams
- */
-public interface IDevice {
- /**
- * Get the primary key for this device.
- * @return the primary key
- */
- public Long getDeviceKey();
-
- /**
- * Get the MAC address of the device as a Long value.
- * @return the MAC address for the device
- */
- public long getMACAddress();
-
- /**
- * Get the MAC address of the device as a String value.
- * @return the MAC address for the device
- */
- public String getMACAddressString();
-
- /**
- * Get all unique VLAN IDs for the device. If the device has untagged
- * entities, then the value -1 will be returned.
- * @return an array containing all unique VLAN IDs for the device.
- */
- public Short[] getVlanId();
-
- /**
- * Get all unique IPv4 addresses associated with the device.
- * @return an array containing the unique IPv4 addresses for the device.
- */
- public Integer[] getIPv4Addresses();
-
- /**
- * Get all unique attachment points associated with the device. This will
- * not include any blocked attachment points.
- * @return an array containing all unique attachment points for the device
- */
- public SwitchPort[] getAttachmentPoints();
-
- /**
- * Get all unique attachment points associated with the device.
- * @param includeError whether to include blocked attachment points.
- * Blocked attachment points should not be used for forwarding, but
- * could be useful to show to a user
- * @return an array containing all unique attachment points for the device
- */
- public SwitchPort[] getAttachmentPoints(boolean includeError);
-
- /**
- * Returns all unique VLAN IDs for the device that were observed on
- * the given switch port
- * @param swp the switch port to query
- * @return an array containing the unique VLAN IDs
- */
- public Short[] getSwitchPortVlanIds(SwitchPort swp);
-
- /**
- * Get the most recent timestamp for this device
- * @return the last seen timestamp
- */
- public Date getLastSeen();
-
- /**
- * Get the entity class for the device.
- * @return the entity class
- * @see IEntityClassifierService
- */
- public IEntityClass getEntityClass();
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceListener.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceListener.java
deleted file mode 100644
index 3c3d599..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceListener.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager;
-
-/**
- * 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 {
- /**
- * Called when a new Device is found
- * @param device the device that changed
- */
- public void deviceAdded(IDevice device);
-
- /**
- * Called when a Device is removed, this typically occurs when the port the
- * Device is attached to goes down, or the switch it is attached to is
- * removed.
- * @param device the device that changed
- */
- public void deviceRemoved(IDevice device);
-
- /**
- * Called when a Device has moved to a new location on the network. Note
- * that either the switch or the port or both has changed.
- *
- * @param device the device that changed
- */
- public void deviceMoved(IDevice device);
-
- /**
- * Called when a network address has been added or remove from a device
- *
- * @param device the device that changed
- */
- public void deviceIPV4AddrChanged(IDevice device);
-
- /**
- * Called when a VLAN tag for the device has been added or removed
- * @param device the device that changed
- */
- public void deviceVlanChanged(IDevice device);
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
deleted file mode 100755
index ad29a94..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
-* Copyright 2011,2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager;
-
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Iterator;
-
-import net.floodlightcontroller.core.FloodlightContextStore;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-/**
- * Device manager allows interacting with devices on the network. Note
- * that under normal circumstances, {@link Device} objects should be retrieved
- * from the {@link FloodlightContext} rather than from {@link IDeviceManager}.
- */
-public interface IDeviceService extends IFloodlightService {
- /**
- * Fields used in devices for indexes and querying
- * @see IDeviceService#addIndex
- */
- enum DeviceField {
- MAC, IPV4, VLAN, SWITCH, PORT
- }
-
- /**
- * The source device for the current packet-in, if applicable.
- */
- public static final String CONTEXT_SRC_DEVICE =
- "net.floodlightcontroller.devicemanager.srcDevice";
-
- /**
- * The destination device for the current packet-in, if applicable.
- */
- public static final String CONTEXT_DST_DEVICE =
- "net.floodlightcontroller.devicemanager.dstDevice";
-
- /**
- * A FloodlightContextStore object that can be used to interact with the
- * FloodlightContext information created by BVS manager.
- */
- public static final FloodlightContextStore<IDevice> fcStore =
- new FloodlightContextStore<IDevice>();
-
- /**
- * Get the device with the given device key.
- *
- * @param deviceKey the key to search for
- * @return the device associated with the key, or null if no such device
- * @see IDevice#getDeviceKey()
- */
- public IDevice getDevice(Long deviceKey);
-
- /**
- * Search for a device exactly matching the provided device fields. This
- * is the same lookup process that is used for packet_in processing and
- * device learning. Thus, findDevice() can be used to match flow entries
- * from switches to devices.
- * Only the key fields as defined by the {@link IEntityClassifierService} will
- * be important in this search. All key fields MUST be supplied.
- *
- *{@link queryDevices()} might be more appropriate!
- *
- * @param macAddress The MAC address
- * @param vlan the VLAN. Null means no VLAN and is valid even if VLAN is a
- * key field.
- * @param ipv4Address the ipv4 address
- * @param switchDPID the switch DPID
- * @param switchPort the switch port
- * @return an {@link IDevice} or null if no device is found.
- * @see IDeviceManager#setEntityClassifier(IEntityClassifierService)
- * @throws IllegalArgumentException if not all key fields of the
- * current {@link IEntityClassifierService} are specified.
- */
- public IDevice findDevice(long macAddress, Short vlan,
- Integer ipv4Address, Long switchDPID,
- Integer switchPort)
- throws IllegalArgumentException;
-
- /**
- * Get a destination device using entity fields that corresponds with
- * the given source device. The source device is important since
- * there could be ambiguity in the destination device without the
- * attachment point information.
- *
- * @param source the source device. The returned destination will be
- * in the same entity class as the source.
- * @param macAddress The MAC address for the destination
- * @param vlan the VLAN if available
- * @param ipv4Address The IP address if available.
- * @return an {@link IDevice} or null if no device is found.
- * @see IDeviceService#findDevice(long, Short, Integer, Long,
- * Integer)
- * @throws IllegalArgumentException if not all key fields of the
- * source's {@link IEntityClass} are specified.
- */
- public IDevice findDestDevice(IDevice source,
- long macAddress, Short vlan,
- Integer ipv4Address)
- throws IllegalArgumentException;
-
- /**
- * Get an unmodifiable collection view over all devices currently known.
- * @return the collection of all devices
- */
- public Collection<? extends IDevice> getAllDevices();
-
- /**
- * Create an index over a set of fields. This allows efficient lookup
- * of devices when querying using the indexed set of specified fields.
- * The index must be registered before any device learning takes place,
- * or it may be incomplete. It's OK if this is called multiple times with
- * the same fields; only one index will be created for each unique set of
- * fields.
- *
- * @param perClass set to true if the index should be maintained for each
- * entity class separately.
- * @param keyFields the set of fields on which to index
- */
- public void addIndex(boolean perClass,
- EnumSet<DeviceField> keyFields);
-
- /**
- * Find devices that match the provided query. Any fields that are
- * null will not be included in the query. If there is an index for
- * the query, then it will be performed efficiently using the index.
- * Otherwise, there will be a full scan of the device list.
- *
- * @param macAddress The MAC address
- * @param vlan the VLAN
- * @param ipv4Address the ipv4 address
- * @param switchDPID the switch DPID
- * @param switchPort the switch port
- * @return an iterator over a set of devices matching the query
- * @see IDeviceService#queryClassDevices(IEntityClass, Long,
- * Short, Integer, Long, Integer)
- */
- public Iterator<? extends IDevice> queryDevices(Long macAddress,
- Short vlan,
- Integer ipv4Address,
- Long switchDPID,
- Integer switchPort);
-
- /**
- * Find devices that match the provided query. Only the index for
- * the class of the specified reference device will be searched.
- * Any fields that are null will not be included in the query. If
- * there is an index for the query, then it will be performed
- * efficiently using the index. Otherwise, there will be a full scan
- * of the device list.
- *
- * @param reference The reference device to refer to when finding
- * entity classes.
- * @param macAddress The MAC address
- * @param vlan the VLAN
- * @param ipv4Address the ipv4 address
- * @param switchDPID the switch DPID
- * @param switchPort the switch port
- * @return an iterator over a set of devices matching the query
- * @see IDeviceService#queryClassDevices(Long,
- * Short, Integer, Long, Integer)
- */
- public Iterator<? extends IDevice> queryClassDevices(IDevice reference,
- Long macAddress,
- Short vlan,
- Integer ipv4Address,
- Long switchDPID,
- Integer switchPort);
-
- /**
- * Adds a listener to listen for IDeviceManagerServices notifications
- *
- * @param listener The listener that wants the notifications
- */
- public void addListener(IDeviceListener listener);
-
- /**
- * Specify points in the network where attachment points are not to
- * be learned.
- * @param sw
- * @param port
- */
- public void addSuppressAPs(long swId, short port);
-
- public void removeSuppressAPs(long swId, short port);
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClass.java b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClass.java
deleted file mode 100644
index bb077f1..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClass.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
-* Copyright 2011,2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager;
-
-import java.util.EnumSet;
-
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import net.floodlightcontroller.devicemanager.internal.Device;
-
-/**
- * Entities within an entity class are grouped into {@link Device} objects
- * based on the {@link IEntityClass}, and the key fields specified by the entity
- * class. A set of entities are considered to be the same device if and only
- * if they belong to the same entity class and they match on all key fields
- * for that entity class. A field is effectively wildcarded by not including
- * it in the list of key fields returned by {@link IEntityClassifierService} and/or
- * {@link IEntityClass}.
- *
- * Note that if you're not using static objects, you'll need to override
- * {@link Object#equals(Object)} and {@link Object#hashCode()}.
- *
- * @author readams
- *
- */
-public interface IEntityClass {
- /**
- * Return the set of key fields for this entity class. Entities
- * belonging to this class that differ in fields not included in
- * this collection will be considered the same device. The key
- * fields for an entity class must not change unless associated
- * with a flush of that entity class.
- *
- * @return a set containing the fields that should not
- * be wildcarded. May be null to indicate that all fields are key fields.
- */
- EnumSet<DeviceField> getKeyFields();
-
- /**
- * Returns a user-friendly, unique name for this EntityClass
- * @return the name of the entity class
- */
- String getName();
-}
-
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java
deleted file mode 100644
index 6029af1..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager;
-
-import java.util.Set;
-
-/**
- * Implementors of this interface can receive updates from DeviceManager about
- * the changes entity Classes.
- *
- * @author Ananth Suryanarayana (Ananth.Suryanarayana@bigswitch.com)
- */
-public interface IEntityClassListener {
-
- /**
- * Process entity classes change event.
- * @param entityClassNames Set of entity classes changed
- */
- public void entityClassChanged(Set<String> entityClassNames);
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java
deleted file mode 100644
index 2569a7d..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
-* Copyright 2011,2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager;
-
-import java.util.Collection;
-import java.util.EnumSet;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import net.floodlightcontroller.devicemanager.internal.Entity;
-
-/**
- * A component that wishes to participate in entity classification needs to
- * implement the IEntityClassifier interface, and register with the Device
- * Manager as an entity classifier. An entity is classified by the classifier
- * into an {@link IEntityClass}
- *
- * @author readams
- */
-public interface IEntityClassifierService extends IFloodlightService {
- /**
- * Classify the given entity into an IEntityClass. It is important
- * that the key fields returned by {@link IEntityClassifierService#getKeyFields()}
- * be sufficient for classifying entities. That is, if two entities are
- * identical except for a field that is not a key field, they must be
- * assigned the same class. Furthermore, entity classification must be
- * transitive: For all entities x, y, z, if x and y belong to a class c, and
- * y and z belong class c, then x and z must belong to class c.
- *
- * @param entity the entity to classify
- * @return the IEntityClass resulting from the classification.
- * @see IEntityClassifierService#getKeyFields()
- */
- IEntityClass classifyEntity(Entity entity);
-
- /**
- * Return the most general list of fields that should be used as key
- * fields. If devices differ in any fields not listed here, they can
- * never be considered a different device by any {@link IEntityClass}
- * returned by {@link IEntityClassifierService#classifyEntity}. The key fields
- * for an entity classifier must not change unless associated with a
- * flush of all entity state. The list of key fields must be the union
- * of all key fields that could be returned by
- * {@link IEntityClass#getKeyFields()}.
- *
- * @return a set containing the fields that should not be
- * wildcarded. May be null to indicate that all fields are key fields.
- * @see {@link IEntityClass#getKeyFields()}
- * @see {@link IEntityClassifierService#classifyEntity}
- */
- EnumSet<DeviceField> getKeyFields();
-
- /**
- * Reclassify the given entity into a class. When reclassifying entities,
- * it can be helpful to take into account the current classification either
- * as an optimization or to allow flushing any cached state tied to the key
- * for that device. The entity will be assigned to a new device with a new
- * object if the entity class returned is different from the entity class for
- * curDevice.
- *
- * <p>Note that you must take steps to ensure you always return classes
- * in some consistent ordering.
-
- * @param curDevice the device currently associated with the entity
- * @param entity the entity to reclassify
- * @return the IEntityClass resulting from the classification
- */
- IEntityClass reclassifyEntity(IDevice curDevice,
- Entity entity);
-
- /**
- * Once reclassification is complete for a device, this method will be
- * called. If any entities within the device changed their classification,
- * it will split into one or more new devices for each of the entities. If
- * two devices are merged because of a reclassification, then this will be
- * called on each of the devices, with the same device in the newDevices
- * collection.
- *
- * @param oldDevice the original device object
- * @param newDevices all the new devices derived from the entities of the
- * old device. If null, the old device was unchanged.
- */
- void deviceUpdate(IDevice oldDevice,
- Collection<? extends IDevice> newDevices);
-
- /**
- * Adds a listener to listen for IEntityClassifierServices notifications
- *
- * @param listener The listener that wants the notifications
- */
- public void addListener(IEntityClassListener listener);
-}
-
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java b/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java
deleted file mode 100644
index 7426163..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
-* Copyright 2012 Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager;
-
-import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
-
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-import org.codehaus.jackson.map.ser.ToStringSerializer;
-
-/**
- * A simple switch DPID/port pair
- * @author readams
- *
- */
-public class SwitchPort {
- @JsonSerialize(using=ToStringSerializer.class)
- public enum ErrorStatus {
- DUPLICATE_DEVICE("duplicate-device");
-
- private String value;
- ErrorStatus(String v) {
- value = v;
- }
-
- @Override
- public String toString() {
- return value;
- }
-
- public static ErrorStatus fromString(String str) {
- for (ErrorStatus m : ErrorStatus.values()) {
- if (m.value.equals(str)) {
- return m;
- }
- }
- return null;
- }
- }
-
- protected long switchDPID;
- protected int port;
- ErrorStatus errorStatus;
-
- /**
- * Simple constructor
- * @param switchDPID the dpid
- * @param port the port
- * @param errorStatus any error status for the switch port
- */
- public SwitchPort(long switchDPID, int port, ErrorStatus errorStatus) {
- super();
- this.switchDPID = switchDPID;
- this.port = port;
- this.errorStatus = errorStatus;
- }
-
- /**
- * Simple constructor
- * @param switchDPID the dpid
- * @param port the port
- */
- public SwitchPort(long switchDPID, int port) {
- super();
- this.switchDPID = switchDPID;
- this.port = port;
- this.errorStatus = null;
- }
-
- // ***************
- // Getters/Setters
- // ***************
-
- @JsonSerialize(using=DPIDSerializer.class)
- public long getSwitchDPID() {
- return switchDPID;
- }
-
- public int getPort() {
- return port;
- }
-
- public ErrorStatus getErrorStatus() {
- return errorStatus;
- }
-
- // ******
- // Object
- // ******
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result
- + ((errorStatus == null)
- ? 0
- : errorStatus.hashCode());
- result = prime * result + port;
- result = prime * result + (int) (switchDPID ^ (switchDPID >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- SwitchPort other = (SwitchPort) obj;
- if (errorStatus != other.errorStatus) return false;
- if (port != other.port) return false;
- if (switchDPID != other.switchDPID) return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "SwitchPort [switchDPID=" + switchDPID + ", port=" + port
- + ", errorStatus=" + errorStatus + "]";
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/AttachmentPoint.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/AttachmentPoint.java
deleted file mode 100644
index a08a3a5..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/AttachmentPoint.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Copyright 2011,2012 Big Switch Networks, Inc.
- * Originally created by David Erickson, Stanford 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- **/
-
-/**
- * @author Srini
- */
-
-package net.floodlightcontroller.devicemanager.internal;
-
-public class AttachmentPoint {
- long sw;
- short port;
- long activeSince;
- long lastSeen;
-
- // Timeout for moving attachment points from OF/broadcast
- // domain to another.
- public static final long INACTIVITY_INTERVAL = 30000; // 30 seconds
- public static final long EXTERNAL_TO_EXTERNAL_TIMEOUT = 5000; // 5 seconds
- public static final long OPENFLOW_TO_EXTERNAL_TIMEOUT = 30000; // 30 seconds
- public static final long CONSISTENT_TIMEOUT = 30000; // 30 seconds
-
- public AttachmentPoint(long sw, short port, long activeSince,
- long lastSeen) {
- this.sw = sw;
- this.port = port;
- this.activeSince = activeSince;
- this.lastSeen = lastSeen;
- }
-
- public AttachmentPoint(long sw, short port, long lastSeen) {
- this.sw = sw;
- this.port = port;
- this.lastSeen = lastSeen;
- this.activeSince = lastSeen;
- }
-
- public AttachmentPoint(AttachmentPoint ap) {
- this.sw = ap.sw;
- this.port = ap.port;
- this.activeSince = ap.activeSince;
- this.lastSeen = ap.lastSeen;
- }
-
- public long getSw() {
- return sw;
- }
- public void setSw(long sw) {
- this.sw = sw;
- }
- public short getPort() {
- return port;
- }
- public void setPort(short port) {
- this.port = port;
- }
- public long getActiveSince() {
- return activeSince;
- }
- public void setActiveSince(long activeSince) {
- this.activeSince = activeSince;
- }
- public long getLastSeen() {
- return lastSeen;
- }
- public void setLastSeen(long lastSeen) {
- if (this.lastSeen + INACTIVITY_INTERVAL < lastSeen)
- this.activeSince = lastSeen;
- if (this.lastSeen < lastSeen)
- this.lastSeen = lastSeen;
- }
-
- /**
- * Hash is generated using only switch and port
- */
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + port;
- result = prime * result + (int) (sw ^ (sw >>> 32));
- return result;
- }
-
- /**
- * Compares only the switch and port
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- AttachmentPoint other = (AttachmentPoint) obj;
- if (port != other.port)
- return false;
- if (sw != other.sw)
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "AttachmentPoint [sw=" + sw + ", port=" + port
- + ", activeSince=" + activeSince + ", lastSeen=" + lastSeen
- + "]";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java
deleted file mode 100644
index faed0d4..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
-* Copyright 2011,2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.IEntityClassListener;
-import net.floodlightcontroller.devicemanager.IEntityClassifierService;
-
-/**
- * This is a default entity classifier that simply classifies all
- * entities into a fixed entity class, with key fields of MAC and VLAN.
- * @author readams
- */
-public class DefaultEntityClassifier implements
- IEntityClassifierService,
- IFloodlightModule
-{
- /**
- * A default fixed entity class
- */
- protected static class DefaultEntityClass implements IEntityClass {
- String name;
-
- public DefaultEntityClass(String name) {
- this.name = name;
- }
-
- @Override
- public EnumSet<IDeviceService.DeviceField> getKeyFields() {
- return keyFields;
- }
-
- @Override
- public String getName() {
- return name;
- }
- }
-
- protected static EnumSet<DeviceField> keyFields;
- static {
- keyFields = EnumSet.of(DeviceField.MAC, DeviceField.VLAN);
- }
- protected static DefaultEntityClass entityClass =
- new DefaultEntityClass("DefaultEntityClass");
-
- @Override
- public IEntityClass classifyEntity(Entity entity) {
- return entityClass;
- }
-
- @Override
- public IEntityClass reclassifyEntity(IDevice curDevice,
- Entity entity) {
- return entityClass;
- }
-
- @Override
- public void deviceUpdate(IDevice oldDevice,
- Collection<? extends IDevice> newDevices) {
- // no-op
- }
-
- @Override
- public EnumSet<DeviceField> getKeyFields() {
- return keyFields;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IEntityClassifierService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- // We are the class that implements the service
- m.put(IEntityClassifierService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>>
- getModuleDependencies() {
- // No dependencies
- return null;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- // no-op
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- // no-op
- }
-
- @Override
- public void addListener(IEntityClassListener listener) {
- // no-op
-
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
deleted file mode 100755
index 05ebcf3..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
+++ /dev/null
@@ -1,725 +0,0 @@
-/**
- * Copyright 2011,2012 Big Switch Networks, Inc.
- * Originally created by David Erickson, Stanford 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- **/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeSet;
-
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import net.floodlightcontroller.devicemanager.web.DeviceSerializer;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.devicemanager.SwitchPort.ErrorStatus;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.topology.ITopologyService;
-
-/**
- * Concrete implementation of {@link IDevice}
- * @author readams
- */
-@JsonSerialize(using=DeviceSerializer.class)
-public class Device implements IDevice {
- protected final static Logger log =
- LoggerFactory.getLogger(Device.class);
-
- protected Long deviceKey;
- protected DeviceManagerImpl deviceManager;
-
- protected Entity[] entities;
- protected IEntityClass entityClass;
-
- protected String macAddressString;
-
- /**
- * These are the old attachment points for the device that were
- * valid no more than INACTIVITY_TIME ago.
- */
- protected List<AttachmentPoint> oldAPs;
- /**
- * The current attachment points for the device.
- */
- protected List<AttachmentPoint> attachmentPoints;
- // ************
- // Constructors
- // ************
-
- /**
- * Create a device from an entities
- * @param deviceManager the device manager for this device
- * @param deviceKey the unique identifier for this device object
- * @param entity the initial entity for the device
- * @param entityClass the entity classes associated with the entity
- */
- public Device(DeviceManagerImpl deviceManager,
- Long deviceKey,
- Entity entity,
- IEntityClass entityClass) {
- this.deviceManager = deviceManager;
- this.deviceKey = deviceKey;
- this.entities = new Entity[] {entity};
- this.macAddressString =
- HexString.toHexString(entity.getMacAddress(), 6);
- this.entityClass = entityClass;
- Arrays.sort(this.entities);
-
- this.oldAPs = null;
- this.attachmentPoints = null;
-
- if (entity.getSwitchDPID() != null &&
- entity.getSwitchPort() != null){
- long sw = entity.getSwitchDPID();
- short port = entity.getSwitchPort().shortValue();
-
- if (deviceManager.isValidAttachmentPoint(sw, port)) {
- AttachmentPoint ap;
- ap = new AttachmentPoint(sw, port,
-entity.getLastSeenTimestamp().getTime());
-
- this.attachmentPoints = new ArrayList<AttachmentPoint>();
- this.attachmentPoints.add(ap);
- }
- }
- }
-
- /**
- * Create a device from a set of entities
- * @param deviceManager the device manager for this device
- * @param deviceKey the unique identifier for this device object
- * @param entities the initial entities for the device
- * @param entityClass the entity class associated with the entities
- */
- public Device(DeviceManagerImpl deviceManager,
- Long deviceKey,
- Collection<AttachmentPoint> oldAPs,
- Collection<AttachmentPoint> attachmentPoints,
- Collection<Entity> entities,
- IEntityClass entityClass) {
- this.deviceManager = deviceManager;
- this.deviceKey = deviceKey;
- this.entities = entities.toArray(new Entity[entities.size()]);
- this.oldAPs = null;
- this.attachmentPoints = null;
- if (oldAPs != null) {
- this.oldAPs =
- new ArrayList<AttachmentPoint>(oldAPs);
- }
- if (attachmentPoints != null) {
- this.attachmentPoints =
- new ArrayList<AttachmentPoint>(attachmentPoints);
- }
- this.macAddressString =
- HexString.toHexString(this.entities[0].getMacAddress(), 6);
- this.entityClass = entityClass;
- Arrays.sort(this.entities);
- }
-
- /**
- * Construct a new device consisting of the entities from the old device
- * plus an additional entity
- * @param device the old device object
- * @param newEntity the entity to add. newEntity must be have the same
- * entity class as device
- */
- public Device(Device device,
- Entity newEntity) {
- this.deviceManager = device.deviceManager;
- this.deviceKey = device.deviceKey;
- this.entities = Arrays.<Entity>copyOf(device.entities,
- device.entities.length + 1);
- this.entities[this.entities.length - 1] = newEntity;
- Arrays.sort(this.entities);
- this.oldAPs = null;
- if (device.oldAPs != null) {
- this.oldAPs =
- new ArrayList<AttachmentPoint>(device.oldAPs);
- }
- this.attachmentPoints = null;
- if (device.attachmentPoints != null) {
- this.attachmentPoints =
- new ArrayList<AttachmentPoint>(device.attachmentPoints);
- }
-
- this.macAddressString =
- HexString.toHexString(this.entities[0].getMacAddress(), 6);
-
- this.entityClass = device.entityClass;
- }
-
- /**
- * Given a list of attachment points (apList), the procedure would return
- * a map of attachment points for each L2 domain. L2 domain id is the key.
- * @param apList
- * @return
- */
- private Map<Long, AttachmentPoint> getAPMap(List<AttachmentPoint> apList) {
-
- if (apList == null) return null;
- ITopologyService topology = deviceManager.topology;
-
- // Get the old attachment points and sort them.
- List<AttachmentPoint>oldAP = new ArrayList<AttachmentPoint>();
- if (apList != null) oldAP.addAll(apList);
-
- // Remove invalid attachment points before sorting.
- List<AttachmentPoint>tempAP =
- new ArrayList<AttachmentPoint>();
- for(AttachmentPoint ap: oldAP) {
- if (deviceManager.isValidAttachmentPoint(ap.getSw(), ap.getPort())){
- tempAP.add(ap);
- }
- }
- oldAP = tempAP;
-
- Collections.sort(oldAP, deviceManager.apComparator);
-
- // Map of attachment point by L2 domain Id.
- Map<Long, AttachmentPoint> apMap = new HashMap<Long, AttachmentPoint>();
-
- for(int i=0; i<oldAP.size(); ++i) {
- AttachmentPoint ap = oldAP.get(i);
- // if this is not a valid attachment point, continue
- if (!deviceManager.isValidAttachmentPoint(ap.getSw(),
- ap.getPort()))
- continue;
-
- long id = topology.getL2DomainId(ap.getSw());
- apMap.put(id, ap);
- }
-
- if (apMap.isEmpty()) return null;
- return apMap;
- }
-
- /**
- * Remove all attachment points that are older than INACTIVITY_INTERVAL
- * from the list.
- * @param apList
- * @return
- */
- private boolean removeExpiredAttachmentPoints(List<AttachmentPoint>apList) {
-
- List<AttachmentPoint> expiredAPs = new ArrayList<AttachmentPoint>();
-
- if (apList == null) return false;
-
- for(AttachmentPoint ap: apList) {
- if (ap.getLastSeen() + AttachmentPoint.INACTIVITY_INTERVAL <
- System.currentTimeMillis())
- expiredAPs.add(ap);
- }
- if (expiredAPs.size() > 0) {
- apList.removeAll(expiredAPs);
- return true;
- } else return false;
- }
-
- /**
- * Get a list of duplicate attachment points, given a list of old attachment
- * points and one attachment point per L2 domain. Given a true attachment
- * point in the L2 domain, say trueAP, another attachment point in the
- * same L2 domain, say ap, is duplicate if:
- * 1. ap is inconsistent with trueAP, and
- * 2. active time of ap is after that of trueAP; and
- * 3. last seen time of ap is within the last INACTIVITY_INTERVAL
- * @param oldAPList
- * @param apMap
- * @return
- */
- List<AttachmentPoint> getDuplicateAttachmentPoints(List<AttachmentPoint>oldAPList,
- Map<Long, AttachmentPoint>apMap) {
- ITopologyService topology = deviceManager.topology;
- List<AttachmentPoint> dupAPs = new ArrayList<AttachmentPoint>();
- long timeThreshold = System.currentTimeMillis() -
- AttachmentPoint.INACTIVITY_INTERVAL;
-
- if (oldAPList == null || apMap == null)
- return dupAPs;
-
- for(AttachmentPoint ap: oldAPList) {
- long id = topology.getL2DomainId(ap.getSw());
- AttachmentPoint trueAP = apMap.get(id);
-
- if (trueAP == null) continue;
- boolean c = (topology.isConsistent(trueAP.getSw(), trueAP.getPort(),
- ap.getSw(), ap.getPort()));
- boolean active = (ap.getActiveSince() > trueAP.getActiveSince());
- boolean last = ap.getLastSeen() > timeThreshold;
- if (!c && active && last) {
- dupAPs.add(ap);
- }
- }
-
- return dupAPs;
- }
-
- /**
- * Update the known attachment points. This method is called whenever
- * topology changes. The method returns true if there's any change to
- * the list of attachment points -- which indicates a possible device
- * move.
- * @return
- */
- protected boolean updateAttachmentPoint() {
- boolean moved = false;
-
- if (attachmentPoints == null || attachmentPoints.isEmpty())
- return false;
-
- List<AttachmentPoint> apList = new ArrayList<AttachmentPoint>();
- if (attachmentPoints != null) apList.addAll(attachmentPoints);
- Map<Long, AttachmentPoint> newMap = getAPMap(apList);
- if (newMap == null || newMap.size() != apList.size()) {
- moved = true;
- }
-
- // Prepare the new attachment point list.
- if (moved) {
- List<AttachmentPoint> newAPList =
- new ArrayList<AttachmentPoint>();
- if (newMap != null) newAPList.addAll(newMap.values());
- this.attachmentPoints = newAPList;
- }
-
- // Set the oldAPs to null.
- this.oldAPs = null;
- return moved;
- }
-
- /**
- * Update the list of attachment points given that a new packet-in
- * was seen from (sw, port) at time (lastSeen). The return value is true
- * if there was any change to the list of attachment points for the device
- * -- which indicates a device move.
- * @param sw
- * @param port
- * @param lastSeen
- * @return
- */
- protected boolean updateAttachmentPoint(long sw, short port, long lastSeen){
- ITopologyService topology = deviceManager.topology;
- List<AttachmentPoint> oldAPList;
- List<AttachmentPoint> apList;
- boolean oldAPFlag = false;
-
- if (!deviceManager.isValidAttachmentPoint(sw, port)) return false;
- AttachmentPoint newAP = new AttachmentPoint(sw, port, lastSeen);
-
- //Copy the oldAP and ap list.
- apList = new ArrayList<AttachmentPoint>();
- if (attachmentPoints != null) apList.addAll(attachmentPoints);
- oldAPList = new ArrayList<AttachmentPoint>();
- if (oldAPs != null) oldAPList.addAll(oldAPs);
-
- // if the sw, port is in old AP, remove it from there
- // and update the lastSeen in that object.
- if (oldAPList.contains(newAP)) {
- int index = oldAPList.indexOf(newAP);
- newAP = oldAPList.remove(index);
- newAP.setLastSeen(lastSeen);
- this.oldAPs = oldAPList;
- oldAPFlag = true;
- }
-
- // newAP now contains the new attachment point.
-
- // Get the APMap is null or empty.
- Map<Long, AttachmentPoint> apMap = getAPMap(apList);
- if (apMap == null || apMap.isEmpty()) {
- apList.add(newAP);
- attachmentPoints = apList;
- return true;
- }
-
- long id = topology.getL2DomainId(sw);
- AttachmentPoint oldAP = apMap.get(id);
-
- if (oldAP == null) // No attachment on this L2 domain.
- {
- apList = new ArrayList<AttachmentPoint>();
- apList.addAll(apMap.values());
- apList.add(newAP);
- this.attachmentPoints = apList;
- return true; // new AP found on an L2 island.
- }
-
- // There is already a known attachment point on the same L2 island.
- // we need to compare oldAP and newAP.
- if (oldAP.equals(newAP)) {
- // nothing to do here. just the last seen has to be changed.
- if (newAP.lastSeen > oldAP.lastSeen) {
- oldAP.setLastSeen(newAP.lastSeen);
- }
- this.attachmentPoints =
- new ArrayList<AttachmentPoint>(apMap.values());
- return false; // nothing to do here.
- }
-
- int x = deviceManager.apComparator.compare(oldAP, newAP);
- if (x < 0) {
- // newAP replaces oldAP.
- apMap.put(id, newAP);
- this.attachmentPoints =
- new ArrayList<AttachmentPoint>(apMap.values());
-
- oldAPList = new ArrayList<AttachmentPoint>();
- if (oldAPs != null) oldAPList.addAll(oldAPs);
- oldAPList.add(oldAP);
- this.oldAPs = oldAPList;
- if (!topology.isInSameBroadcastDomain(oldAP.getSw(), oldAP.getPort(),
- newAP.getSw(), newAP.getPort()))
- return true; // attachment point changed.
- } else if (oldAPFlag) {
- // retain oldAP as is. Put the newAP in oldAPs for flagging
- // possible duplicates.
- oldAPList = new ArrayList<AttachmentPoint>();
- if (oldAPs != null) oldAPList.addAll(oldAPs);
- // Add ot oldAPList only if it was picked up from the oldAPList
- oldAPList.add(newAP);
- this.oldAPs = oldAPList;
- }
- return false;
- }
-
- /**
- * Delete (sw,port) from the list of list of attachment points
- * and oldAPs.
- * @param sw
- * @param port
- * @return
- */
- public boolean deleteAttachmentPoint(long sw, short port) {
- AttachmentPoint ap = new AttachmentPoint(sw, port, 0);
-
- if (this.oldAPs != null) {
- ArrayList<AttachmentPoint> apList = new ArrayList<AttachmentPoint>();
- apList.addAll(this.oldAPs);
- int index = apList.indexOf(ap);
- if (index > 0) {
- apList.remove(index);
- this.oldAPs = apList;
- }
- }
-
- if (this.attachmentPoints != null) {
- ArrayList<AttachmentPoint> apList = new ArrayList<AttachmentPoint>();
- apList.addAll(this.attachmentPoints);
- int index = apList.indexOf(ap);
- if (index > 0) {
- apList.remove(index);
- this.attachmentPoints = apList;
- return true;
- }
- }
- return false;
- }
-
- public boolean deleteAttachmentPoint(long sw) {
- boolean deletedFlag;
- ArrayList<AttachmentPoint> apList;
- ArrayList<AttachmentPoint> modifiedList;
-
- // Delete the APs on switch sw in oldAPs.
- deletedFlag = false;
- apList = new ArrayList<AttachmentPoint>();
- if (this.oldAPs != null)
- apList.addAll(this.oldAPs);
- modifiedList = new ArrayList<AttachmentPoint>();
-
- for(AttachmentPoint ap: apList) {
- if (ap.getSw() == sw) {
- deletedFlag = true;
- } else {
- modifiedList.add(ap);
- }
- }
-
- if (deletedFlag) {
- this.oldAPs = modifiedList;
- }
-
- // Delete the APs on switch sw in attachmentPoints.
- deletedFlag = false;
- apList = new ArrayList<AttachmentPoint>();
- if (this.attachmentPoints != null)
- apList.addAll(this.attachmentPoints);
- modifiedList = new ArrayList<AttachmentPoint>();
-
- for(AttachmentPoint ap: apList) {
- if (ap.getSw() == sw) {
- deletedFlag = true;
- } else {
- modifiedList.add(ap);
- }
- }
-
- if (deletedFlag) {
- this.attachmentPoints = modifiedList;
- return true;
- }
-
- return false;
- }
-
-
- @Override
- public SwitchPort[] getAttachmentPoints() {
- return getAttachmentPoints(false);
- }
-
- @Override
- public SwitchPort[] getAttachmentPoints(boolean includeError) {
- List<SwitchPort> sp = new ArrayList<SwitchPort>();
- SwitchPort [] returnSwitchPorts = new SwitchPort[] {};
- if (attachmentPoints == null) return returnSwitchPorts;
- if (attachmentPoints.isEmpty()) return returnSwitchPorts;
-
-
- // copy ap list.
- List<AttachmentPoint> apList;
- apList = new ArrayList<AttachmentPoint>();
- if (attachmentPoints != null) apList.addAll(attachmentPoints);
- // get AP map.
- Map<Long, AttachmentPoint> apMap = getAPMap(apList);
-
- if (apMap != null) {
- for(AttachmentPoint ap: apMap.values()) {
- SwitchPort swport = new SwitchPort(ap.getSw(),
- ap.getPort());
- sp.add(swport);
- }
- }
-
- if (!includeError)
- return sp.toArray(new SwitchPort[sp.size()]);
-
- List<AttachmentPoint> oldAPList;
- oldAPList = new ArrayList<AttachmentPoint>();
-
- if (oldAPs != null) oldAPList.addAll(oldAPs);
-
- if (removeExpiredAttachmentPoints(oldAPList))
- this.oldAPs = oldAPList;
-
- List<AttachmentPoint> dupList;
- dupList = this.getDuplicateAttachmentPoints(oldAPList, apMap);
- if (dupList != null) {
- for(AttachmentPoint ap: dupList) {
- SwitchPort swport = new SwitchPort(ap.getSw(),
- ap.getPort(),
- ErrorStatus.DUPLICATE_DEVICE);
- sp.add(swport);
- }
- }
- return sp.toArray(new SwitchPort[sp.size()]);
- }
-
- // *******
- // IDevice
- // *******
-
- @Override
- public Long getDeviceKey() {
- return deviceKey;
- }
-
- @Override
- public long getMACAddress() {
- // we assume only one MAC per device for now.
- return entities[0].getMacAddress();
- }
-
- @Override
- public String getMACAddressString() {
- return macAddressString;
- }
-
- @Override
- public Short[] getVlanId() {
- if (entities.length == 1) {
- if (entities[0].getVlan() != null) {
- return new Short[]{ entities[0].getVlan() };
- } else {
- return new Short[] { Short.valueOf((short)-1) };
- }
- }
-
- TreeSet<Short> vals = new TreeSet<Short>();
- for (Entity e : entities) {
- if (e.getVlan() == null)
- vals.add((short)-1);
- else
- vals.add(e.getVlan());
- }
- return vals.toArray(new Short[vals.size()]);
- }
-
- static final EnumSet<DeviceField> ipv4Fields = EnumSet.of(DeviceField.IPV4);
-
- @Override
- public Integer[] getIPv4Addresses() {
- // XXX - TODO we can cache this result. Let's find out if this
- // is really a performance bottleneck first though.
-
- TreeSet<Integer> vals = new TreeSet<Integer>();
- for (Entity e : entities) {
- if (e.getIpv4Address() == null) continue;
-
- // We have an IP address only if among the devices within the class
- // we have the most recent entity with that IP.
- boolean validIP = true;
- Iterator<Device> devices =
- deviceManager.queryClassByEntity(entityClass, ipv4Fields, e);
- while (devices.hasNext()) {
- Device d = devices.next();
- if (deviceKey.equals(d.getDeviceKey()))
- continue;
- for (Entity se : d.entities) {
- if (se.getIpv4Address() != null &&
- se.getIpv4Address().equals(e.getIpv4Address()) &&
- se.getLastSeenTimestamp() != null &&
- 0 < se.getLastSeenTimestamp().
- compareTo(e.getLastSeenTimestamp())) {
- validIP = false;
- break;
- }
- }
- if (!validIP)
- break;
- }
-
- if (validIP)
- vals.add(e.getIpv4Address());
- }
-
- return vals.toArray(new Integer[vals.size()]);
- }
-
- @Override
- public Short[] getSwitchPortVlanIds(SwitchPort swp) {
- TreeSet<Short> vals = new TreeSet<Short>();
- for (Entity e : entities) {
- if (e.switchDPID == swp.getSwitchDPID()
- && e.switchPort == swp.getPort()) {
- if (e.getVlan() == null)
- vals.add(Ethernet.VLAN_UNTAGGED);
- else
- vals.add(e.getVlan());
- }
- }
- return vals.toArray(new Short[vals.size()]);
- }
-
- @Override
- public Date getLastSeen() {
- Date d = null;
- for (int i = 0; i < entities.length; i++) {
- if (d == null ||
- entities[i].getLastSeenTimestamp().compareTo(d) > 0)
- d = entities[i].getLastSeenTimestamp();
- }
- return d;
- }
-
- // ***************
- // Getters/Setters
- // ***************
-
- @Override
- public IEntityClass getEntityClass() {
- return entityClass;
- }
-
- public Entity[] getEntities() {
- return entities;
- }
-
- // ***************
- // Utility Methods
- // ***************
-
- /**
- * Check whether the device contains the specified entity
- * @param entity the entity to search for
- * @return the index of the entity, or <0 if not found
- */
- protected int entityIndex(Entity entity) {
- return Arrays.binarySearch(entities, entity);
- }
-
- // ******
- // Object
- // ******
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Arrays.hashCode(entities);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- Device other = (Device) obj;
- if (!deviceKey.equals(other.deviceKey)) return false;
- if (!Arrays.equals(entities, other.entities)) return false;
- return true;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("Device [deviceKey=");
- builder.append(deviceKey);
- builder.append(", entityClass=");
- builder.append(entityClass.getName());
- builder.append(", MAC=");
- builder.append(macAddressString);
- builder.append(", IPs=[");
- boolean isFirst = true;
- for (Integer ip: getIPv4Addresses()) {
- if (!isFirst)
- builder.append(", ");
- isFirst = false;
- builder.append(IPv4.fromIPv4Address(ip));
- }
- builder.append("], APs=");
- builder.append(Arrays.toString(getAttachmentPoints(true)));
- builder.append("]");
- return builder.toString();
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIndex.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIndex.java
deleted file mode 100644
index 0d8ea75..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIndex.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
-* Copyright 2012 Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Iterator;
-
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-
-/**
- * An index that maps key fields of an entity to device keys
- */
-public abstract class DeviceIndex {
- /**
- * The key fields for this index
- */
- protected EnumSet<DeviceField> keyFields;
-
- /**
- * Construct a new device index using the provided key fields
- * @param keyFields the key fields to use
- */
- public DeviceIndex(EnumSet<DeviceField> keyFields) {
- super();
- this.keyFields = keyFields;
- }
-
- /**
- * Find all device keys in the index that match the given entity
- * on all the key fields for this index
- * @param e the entity to search for
- * @return an iterator over device keys
- */
- public abstract Iterator<Long> queryByEntity(Entity entity);
-
- /**
- * Get all device keys in the index. If certain devices exist
- * multiple times, then these devices may be returned multiple times
- * @return an iterator over device keys
- */
- public abstract Iterator<Long> getAll();
-
- /**
- * Attempt to update an index with the entities in the provided
- * {@link Device}. If the update fails because of a concurrent update,
- * will return false.
- * @param device the device to update
- * @param deviceKey the device key for the device
- * @return true if the update succeeded, false otherwise.
- */
- public abstract boolean updateIndex(Device device, Long deviceKey);
-
- /**
- * Add a mapping from the given entity to the given device key. This
- * update will not fail because of a concurrent update
- * @param device the device to update
- * @param deviceKey the device key for the device
- */
- public abstract void updateIndex(Entity entity, Long deviceKey);
-
- /**
- * Remove the entry for the given entity
- * @param entity the entity to remove
- */
- public abstract void removeEntity(Entity entity);
-
- /**
- * Remove the given device key from the index for the given entity
- * @param entity the entity to search for
- * @param deviceKey the key to remove
- */
- public abstract void removeEntity(Entity entity, Long deviceKey);
-
- /**
- * Remove the give device from the index only if this the collection
- * of others does not contain an entity that is identical on all the key
- * fields for this index.
- * @param entity the entity to search for
- * @param deviceKey the key to remove
- * @param others the others against which to check
- */
- public void removeEntityIfNeeded(Entity entity, Long deviceKey,
- Collection<Entity> others) {
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- for (Entity o : others) {
- IndexedEntity oio = new IndexedEntity(keyFields, o);
- if (oio.equals(ie)) return;
- }
-
- Iterator<Long> keyiter = this.queryByEntity(entity);
- while (keyiter.hasNext()) {
- Long key = keyiter.next();
- if (key.equals(deviceKey)) {
- removeEntity(entity, deviceKey);
- break;
- }
- }
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIndexInterator.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIndexInterator.java
deleted file mode 100644
index 2015bbe..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIndexInterator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
-* Copyright 2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.Iterator;
-
-/**
- * An iterator for handling device index queries
- */
-public class DeviceIndexInterator implements Iterator<Device> {
- private DeviceManagerImpl deviceManager;
- private Iterator<Long> subIterator;
-
- /**
- * Construct a new device index iterator referring to a device manager
- * instance and an iterator over device keys
- *
- * @param deviceManager the device manager
- * @param subIterator an iterator over device keys
- */
- public DeviceIndexInterator(DeviceManagerImpl deviceManager,
- Iterator<Long> subIterator) {
- super();
- this.deviceManager = deviceManager;
- this.subIterator = subIterator;
- }
-
- @Override
- public boolean hasNext() {
- return subIterator.hasNext();
- }
-
- @Override
- public Device next() {
- Long next = subIterator.next();
- return deviceManager.deviceMap.get(next);
- }
-
- @Override
- public void remove() {
- subIterator.remove();
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIterator.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIterator.java
deleted file mode 100644
index 2cbea66..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceIterator.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
-* Copyright 2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.util.FilterIterator;
-
-/**
- * An iterator for handling device queries
- */
-public class DeviceIterator extends FilterIterator<Device> {
- private IEntityClass[] entityClasses;
-
- private Long macAddress;
- private Short vlan;
- private Integer ipv4Address;
- private Long switchDPID;
- private Integer switchPort;
-
- /**
- * Construct a new device iterator over the key fields
- * @param subIterator an iterator over the full data structure to scan
- * @param entityClasses the entity classes to search for
- * @param macAddress The MAC address
- * @param vlan the VLAN
- * @param ipv4Address the ipv4 address
- * @param switchDPID the switch DPID
- * @param switchPort the switch port
- */
- public DeviceIterator(Iterator<Device> subIterator,
- IEntityClass[] entityClasses,
- Long macAddress,
- Short vlan,
- Integer ipv4Address,
- Long switchDPID,
- Integer switchPort) {
- super(subIterator);
- this.entityClasses = entityClasses;
- this.subIterator = subIterator;
- this.macAddress = macAddress;
- this.vlan = vlan;
- this.ipv4Address = ipv4Address;
- this.switchDPID = switchDPID;
- this.switchPort = switchPort;
- }
-
- @Override
- protected boolean matches(Device value) {
- boolean match;
- if (entityClasses != null) {
- IEntityClass clazz = value.getEntityClass();
- if (clazz == null) return false;
-
- match = false;
- for (IEntityClass entityClass : entityClasses) {
- if (clazz.equals(entityClass)) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
- if (macAddress != null) {
- if (macAddress.longValue() != value.getMACAddress())
- return false;
- }
- if (vlan != null) {
- Short[] vlans = value.getVlanId();
- if (Arrays.binarySearch(vlans, vlan) < 0)
- return false;
- }
- if (ipv4Address != null) {
- Integer[] ipv4Addresses = value.getIPv4Addresses();
- if (Arrays.binarySearch(ipv4Addresses, ipv4Address) < 0)
- return false;
- }
- if (switchDPID != null || switchPort != null) {
- SwitchPort[] sps = value.getAttachmentPoints();
- if (sps == null) return false;
-
- match = false;
- for (SwitchPort sp : sps) {
- if (switchDPID != null) {
- if (switchDPID.longValue() != sp.getSwitchDPID())
- return false;
- }
- if (switchPort != null) {
- if (switchPort.intValue() != sp.getPort())
- return false;
- }
- match = true;
- break;
- }
- if (!match) return false;
- }
- return true;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
deleted file mode 100755
index 9956a29..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ /dev/null
@@ -1,1657 +0,0 @@
-/**
- * Copyright 2011,2012 Big Switch Networks, Inc.
- * Originally created by David Erickson, Stanford 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- **/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.IUpdate;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.util.SingletonTask;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceListener;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.IEntityClassListener;
-import net.floodlightcontroller.devicemanager.IEntityClassifierService;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.devicemanager.web.DeviceRoutable;
-import net.floodlightcontroller.packet.ARP;
-import net.floodlightcontroller.packet.DHCP;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.ITopologyListener;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.util.MultiIterator;
-import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
-
-import org.openflow.protocol.OFMatchWithSwDpid;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * DeviceManager creates Devices based upon MAC addresses seen in the network.
- * It tracks any network addresses mapped to the Device, and its location
- * within the network.
- * @author readams
- */
-public class DeviceManagerImpl implements
-IDeviceService, IOFMessageListener, ITopologyListener,
-IFloodlightModule, IEntityClassListener {
- protected final static Logger logger =
- LoggerFactory.getLogger(DeviceManagerImpl.class);
-
- protected IFloodlightProviderService floodlightProvider;
- protected ITopologyService topology;
- protected IRestApiService restApi;
- protected IThreadPoolService threadPool;
-
-
- /**
- * Time in milliseconds before entities will expire
- */
- protected static final int ENTITY_TIMEOUT = 60*60*1000;
-
- /**
- * Time in seconds between cleaning up old entities/devices
- */
- protected static final int ENTITY_CLEANUP_INTERVAL = 60*60;
-
- /**
- * This is the master device map that maps device IDs to {@link Device}
- * objects.
- */
- protected ConcurrentHashMap<Long, Device> deviceMap;
-
- /**
- * Counter used to generate device keys
- */
- protected long deviceKeyCounter = 0;
-
- /**
- * Lock for incrementing the device key counter
- */
- protected Object deviceKeyLock = new Object();
-
- /**
- * This is the primary entity index that contains all entities
- */
- protected DeviceUniqueIndex primaryIndex;
-
- /**
- * This stores secondary indices over the fields in the devices
- */
- protected Map<EnumSet<DeviceField>, DeviceIndex> secondaryIndexMap;
-
- /**
- * This map contains state for each of the {@ref IEntityClass}
- * that exist
- */
- protected ConcurrentHashMap<String, ClassState> classStateMap;
-
- /**
- * This is the list of indices we want on a per-class basis
- */
- protected Set<EnumSet<DeviceField>> perClassIndices;
-
- /**
- * The entity classifier currently in use
- */
- protected IEntityClassifierService entityClassifier;
-
- /**
- * Used to cache state about specific entity classes
- */
- protected class ClassState {
-
- /**
- * The class index
- */
- protected DeviceUniqueIndex classIndex;
-
- /**
- * This stores secondary indices over the fields in the device for the
- * class
- */
- protected Map<EnumSet<DeviceField>, DeviceIndex> secondaryIndexMap;
-
- /**
- * Allocate a new {@link ClassState} object for the class
- * @param clazz the class to use for the state
- */
- public ClassState(IEntityClass clazz) {
- EnumSet<DeviceField> keyFields = clazz.getKeyFields();
- EnumSet<DeviceField> primaryKeyFields =
- entityClassifier.getKeyFields();
- boolean keyFieldsMatchPrimary =
- primaryKeyFields.equals(keyFields);
-
- if (!keyFieldsMatchPrimary)
- classIndex = new DeviceUniqueIndex(keyFields);
-
- secondaryIndexMap =
- new HashMap<EnumSet<DeviceField>, DeviceIndex>();
- for (EnumSet<DeviceField> fields : perClassIndices) {
- secondaryIndexMap.put(fields,
- new DeviceMultiIndex(fields));
- }
- }
- }
-
- /**
- * Device manager event listeners
- */
- protected Set<IDeviceListener> deviceListeners;
-
- public enum DeviceUpdateType {
- ADD, DELETE, CHANGE, MOVED;
- }
-
- /**
- * A device update event to be dispatched
- */
- protected class DeviceUpdate implements IUpdate {
- /**
- * The affected device
- */
- protected IDevice device;
-
- /**
- * The change that was made
- */
- protected DeviceUpdateType updateType;
-
- /**
- * If not added, then this is the list of fields changed
- */
- protected EnumSet<DeviceField> fieldsChanged;
-
- public DeviceUpdate(IDevice device, DeviceUpdateType updateType,
- EnumSet<DeviceField> fieldsChanged) {
- super();
- this.device = device;
- this.updateType = updateType;
- this.fieldsChanged = fieldsChanged;
- }
-
- @Override
- public String toString() {
- String devIdStr = device.getEntityClass().getName() + "::" +
- device.getMACAddressString();
- return "DeviceUpdate [device=" + devIdStr + ", updateType=" + updateType
- + ", fieldsChanged=" + fieldsChanged + "]";
- }
-
- @Override
- public void dispatch() {
- if (logger.isTraceEnabled()) {
- logger.trace("Dispatching device update: {}", this);
- }
- for (IDeviceListener listener : deviceListeners) {
- switch (updateType) {
- case ADD:
- listener.deviceAdded(device);
- break;
- case DELETE:
- listener.deviceRemoved(device);
- break;
- case CHANGE:
- for (DeviceField field : fieldsChanged) {
- switch (field) {
- case IPV4:
- listener.deviceIPV4AddrChanged(device);
- break;
- case SWITCH:
- case PORT:
- //listener.deviceMoved(update.device);
- break;
- case VLAN:
- listener.deviceVlanChanged(device);
- break;
- default:
- logger.debug("Unknown device field changed {}",
- fieldsChanged.toString());
- break;
- }
- }
- break;
- case MOVED:
- listener.deviceMoved(device);
- break;
- }
- }
- }
-
- }
-
- /**
- * AttachmentPointComparator
- *
- * Compares two attachment points and returns the latest one.
- * It is assumed that the two attachment points are in the same
- * L2 domain.
- *
- * @author srini
- */
- protected class AttachmentPointComparator
- implements Comparator<AttachmentPoint> {
- public AttachmentPointComparator() {
- super();
- }
-
- @Override
- public int compare(AttachmentPoint oldAP, AttachmentPoint newAP) {
-
- //First compare based on L2 domain ID;
- long oldSw = oldAP.getSw();
- short oldPort = oldAP.getPort();
- long oldDomain = topology.getL2DomainId(oldSw);
- boolean oldBD = topology.isBroadcastDomainPort(oldSw, oldPort);
-
- long newSw = newAP.getSw();
- short newPort = newAP.getPort();
- long newDomain = topology.getL2DomainId(newSw);
- boolean newBD = topology.isBroadcastDomainPort(newSw, newPort);
-
- if (oldDomain < newDomain) return -1;
- else if (oldDomain > newDomain) return 1;
-
- // We expect that the last seen of the new AP is higher than
- // old AP, if it is not, just reverse and send the negative
- // of the result.
- if (oldAP.getActiveSince() > newAP.getActiveSince())
- return -compare(newAP, oldAP);
-
- long activeOffset = 0;
- if (!topology.isConsistent(oldSw, oldPort, newSw, newPort)) {
- if (!newBD && oldBD) {
- return -1;
- }
- if (newBD && oldBD) {
- activeOffset = AttachmentPoint.EXTERNAL_TO_EXTERNAL_TIMEOUT;
- }
- else if (newBD && !oldBD){
- activeOffset = AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT;
- }
-
- } else {
- // The attachment point is consistent.
- activeOffset = AttachmentPoint.CONSISTENT_TIMEOUT;
- }
-
-
- if ((newAP.getActiveSince() > oldAP.getLastSeen() + activeOffset) ||
- (newAP.getLastSeen() > oldAP.getLastSeen() +
- AttachmentPoint.INACTIVITY_INTERVAL)) {
- return -1;
- }
- return 1;
- }
- }
- /**
- * Comparator for sorting by cluster ID
- */
- public AttachmentPointComparator apComparator;
-
- /**
- * Switch ports where attachment points shouldn't be learned
- */
- private Set<SwitchPort> suppressAPs;
-
- /**
- * Periodic task to clean up expired entities
- */
- public SingletonTask entityCleanupTask;
-
- // *********************
- // IDeviceManagerService
- // *********************
-
- @Override
- public IDevice getDevice(Long deviceKey) {
- return deviceMap.get(deviceKey);
- }
-
- @Override
- public IDevice findDevice(long macAddress, Short vlan,
- Integer ipv4Address, Long switchDPID,
- Integer switchPort)
- throws IllegalArgumentException {
- if (vlan != null && vlan.shortValue() <= 0)
- vlan = null;
- if (ipv4Address != null && ipv4Address == 0)
- ipv4Address = null;
- Entity e = new Entity(macAddress, vlan, ipv4Address, switchDPID,
- switchPort, null);
- if (!allKeyFieldsPresent(e, entityClassifier.getKeyFields())) {
- throw new IllegalArgumentException("Not all key fields specified."
- + " Required fields: " + entityClassifier.getKeyFields());
- }
- return findDeviceByEntity(e);
- }
-
- @Override
- public IDevice findDestDevice(IDevice source, long macAddress,
- Short vlan, Integer ipv4Address)
- throws IllegalArgumentException {
- if (vlan != null && vlan.shortValue() <= 0)
- vlan = null;
- if (ipv4Address != null && ipv4Address == 0)
- ipv4Address = null;
- Entity e = new Entity(macAddress, vlan, ipv4Address,
- null, null, null);
- if (source == null ||
- !allKeyFieldsPresent(e, source.getEntityClass().getKeyFields())) {
- throw new IllegalArgumentException("Not all key fields and/or "
- + " no source device specified. Required fields: " +
- entityClassifier.getKeyFields());
- }
- return findDestByEntity(source, e);
- }
-
- @Override
- public Collection<? extends IDevice> getAllDevices() {
- return Collections.unmodifiableCollection(deviceMap.values());
- }
-
- @Override
- public void addIndex(boolean perClass,
- EnumSet<DeviceField> keyFields) {
- if (perClass) {
- perClassIndices.add(keyFields);
- } else {
- secondaryIndexMap.put(keyFields,
- new DeviceMultiIndex(keyFields));
- }
- }
-
- @Override
- public Iterator<? extends IDevice> queryDevices(Long macAddress,
- Short vlan,
- Integer ipv4Address,
- Long switchDPID,
- Integer switchPort) {
- DeviceIndex index = null;
- if (secondaryIndexMap.size() > 0) {
- EnumSet<DeviceField> keys =
- getEntityKeys(macAddress, vlan, ipv4Address,
- switchDPID, switchPort);
- index = secondaryIndexMap.get(keys);
- }
-
- Iterator<Device> deviceIterator = null;
- if (index == null) {
- // Do a full table scan
- deviceIterator = deviceMap.values().iterator();
- } else {
- // index lookup
- Entity entity = new Entity((macAddress == null ? 0 : macAddress),
- vlan,
- ipv4Address,
- switchDPID,
- switchPort,
- null);
- deviceIterator =
- new DeviceIndexInterator(this, index.queryByEntity(entity));
- }
-
- DeviceIterator di =
- new DeviceIterator(deviceIterator,
- null,
- macAddress,
- vlan,
- ipv4Address,
- switchDPID,
- switchPort);
- return di;
- }
-
- @Override
- public Iterator<? extends IDevice> queryClassDevices(IDevice reference,
- Long macAddress,
- Short vlan,
- Integer ipv4Address,
- Long switchDPID,
- Integer switchPort) {
- IEntityClass entityClass = reference.getEntityClass();
- ArrayList<Iterator<Device>> iterators =
- new ArrayList<Iterator<Device>>();
- ClassState classState = getClassState(entityClass);
-
- DeviceIndex index = null;
- if (classState.secondaryIndexMap.size() > 0) {
- EnumSet<DeviceField> keys =
- getEntityKeys(macAddress, vlan, ipv4Address,
- switchDPID, switchPort);
- index = classState.secondaryIndexMap.get(keys);
- }
-
- Iterator<Device> iter;
- if (index == null) {
- index = classState.classIndex;
- if (index == null) {
- // scan all devices
- return new DeviceIterator(deviceMap.values().iterator(),
- new IEntityClass[] { entityClass },
- macAddress, vlan, ipv4Address,
- switchDPID, switchPort);
- } else {
- // scan the entire class
- iter = new DeviceIndexInterator(this, index.getAll());
- }
- } else {
- // index lookup
- Entity entity =
- new Entity((macAddress == null ? 0 : macAddress),
- vlan,
- ipv4Address,
- switchDPID,
- switchPort,
- null);
- iter = new DeviceIndexInterator(this,
- index.queryByEntity(entity));
- }
- iterators.add(iter);
-
- return new MultiIterator<Device>(iterators.iterator());
- }
-
- protected Iterator<Device> getDeviceIteratorForQuery(Long macAddress,
- Short vlan,
- Integer ipv4Address,
- Long switchDPID,
- Integer switchPort) {
- DeviceIndex index = null;
- if (secondaryIndexMap.size() > 0) {
- EnumSet<DeviceField> keys =
- getEntityKeys(macAddress, vlan, ipv4Address,
- switchDPID, switchPort);
- index = secondaryIndexMap.get(keys);
- }
-
- Iterator<Device> deviceIterator = null;
- if (index == null) {
- // Do a full table scan
- deviceIterator = deviceMap.values().iterator();
- } else {
- // index lookup
- Entity entity = new Entity((macAddress == null ? 0 : macAddress),
- vlan,
- ipv4Address,
- switchDPID,
- switchPort,
- null);
- deviceIterator =
- new DeviceIndexInterator(this, index.queryByEntity(entity));
- }
-
- DeviceIterator di =
- new DeviceIterator(deviceIterator,
- null,
- macAddress,
- vlan,
- ipv4Address,
- switchDPID,
- switchPort);
- return di;
- }
-
- @Override
- public void addListener(IDeviceListener listener) {
- deviceListeners.add(listener);
- }
-
- // ******************
- // IOFMessageListener
- // ******************
-
- @Override
- public String getName() {
- return "devicemanager";
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return ((type == OFType.PACKET_IN || type == OFType.FLOW_MOD)
- && name.equals("topology"));
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return false;
- }
-
- @Override
- public Command receive(IOFSwitch sw, OFMessage msg,
- FloodlightContext cntx) {
- switch (msg.getType()) {
- case PACKET_IN:
- return this.processPacketInMessage(sw,
- (OFPacketIn) msg, cntx);
- default:
- break;
- }
- return Command.CONTINUE;
- }
-
-
- // *****************
- // IFloodlightModule
- // *****************
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IDeviceService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- // We are the class that implements the service
- m.put(IDeviceService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(ITopologyService.class);
- l.add(IRestApiService.class);
- l.add(IThreadPoolService.class);
- l.add(IEntityClassifierService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext fmc) {
- this.perClassIndices =
- new HashSet<EnumSet<DeviceField>>();
- addIndex(true, EnumSet.of(DeviceField.IPV4));
-
- this.deviceListeners = new HashSet<IDeviceListener>();
- this.suppressAPs =
- Collections.synchronizedSet(new HashSet<SwitchPort>());
-
- this.floodlightProvider =
- fmc.getServiceImpl(IFloodlightProviderService.class);
- this.topology =
- fmc.getServiceImpl(ITopologyService.class);
- this.restApi = fmc.getServiceImpl(IRestApiService.class);
- this.threadPool = fmc.getServiceImpl(IThreadPoolService.class);
- this.entityClassifier = fmc.getServiceImpl(IEntityClassifierService.class);
- }
-
- @Override
- public void startUp(FloodlightModuleContext fmc) {
- primaryIndex = new DeviceUniqueIndex(entityClassifier.getKeyFields());
- secondaryIndexMap = new HashMap<EnumSet<DeviceField>, DeviceIndex>();
-
- deviceMap = new ConcurrentHashMap<Long, Device>();
- classStateMap =
- new ConcurrentHashMap<String, ClassState>();
- apComparator = new AttachmentPointComparator();
-
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- if (topology != null)
- topology.addListener(this);
- entityClassifier.addListener(this);
-
- Runnable ecr = new Runnable() {
- @Override
- public void run() {
- cleanupEntities();
- entityCleanupTask.reschedule(ENTITY_CLEANUP_INTERVAL,
- TimeUnit.SECONDS);
- }
- };
- ScheduledExecutorService ses = threadPool.getScheduledExecutor();
- entityCleanupTask = new SingletonTask(ses, ecr);
- entityCleanupTask.reschedule(ENTITY_CLEANUP_INTERVAL,
- TimeUnit.SECONDS);
-
- if (restApi != null) {
- restApi.addRestletRoutable(new DeviceRoutable());
- } else {
- logger.debug("Could not instantiate REST API");
- }
- }
-
- // ****************
- // Internal methods
- // ****************
-
- protected Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi,
- FloodlightContext cntx) {
- Ethernet eth =
- IFloodlightProviderService.bcStore.
- get(cntx,IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
- // Extract source entity information
- Entity srcEntity =
- getSourceEntityFromPacket(eth, sw.getId(), pi.getInPort());
- if (srcEntity == null)
- return Command.STOP;
-
- // Learn/lookup device information
- Device srcDevice = learnDeviceByEntity(srcEntity);
- if (srcDevice == null)
- return Command.STOP;
-
- // Store the source device in the context
- fcStore.put(cntx, CONTEXT_SRC_DEVICE, srcDevice);
-
- // Find the device matching the destination from the entity
- // classes of the source.
- Entity dstEntity = getDestEntityFromPacket(eth);
- Device dstDevice = null;
- if (dstEntity != null) {
- dstDevice =
- findDestByEntity(srcDevice, dstEntity);
- if (dstDevice != null)
- fcStore.put(cntx, CONTEXT_DST_DEVICE, dstDevice);
- }
-
- if (logger.isTraceEnabled()) {
- logger.trace("Received PI: {} on switch {}, port {} *** eth={}" +
- " *** srcDev={} *** dstDev={} *** ",
- new Object[] { pi, sw.getStringId(), pi.getInPort(), eth,
- srcDevice, dstDevice });
- }
- return Command.CONTINUE;
- }
-
- /**
- * Check whether the given attachment point is valid given the current
- * topology
- * @param switchDPID the DPID
- * @param switchPort the port
- * @return true if it's a valid attachment point
- */
- public boolean isValidAttachmentPoint(long switchDPID,
- int switchPort) {
- if (topology.isAttachmentPointPort(switchDPID,
- (short)switchPort) == false)
- return false;
-
- if (suppressAPs.contains(new SwitchPort(switchDPID, switchPort)))
- return false;
-
- return true;
- }
-
- /**
- * Get IP address from packet if the packet is either an ARP
- * or a DHCP packet
- * @param eth
- * @param dlAddr
- * @return
- */
- private int getSrcNwAddr(Ethernet eth, long dlAddr) {
- if (eth.getPayload() instanceof ARP) {
- ARP arp = (ARP) eth.getPayload();
- if ((arp.getProtocolType() == ARP.PROTO_TYPE_IP) &&
- (Ethernet.toLong(arp.getSenderHardwareAddress()) == dlAddr)) {
- return IPv4.toIPv4Address(arp.getSenderProtocolAddress());
- }
- } else if (eth.getPayload() instanceof IPv4) {
- IPv4 ipv4 = (IPv4) eth.getPayload();
- if (ipv4.getPayload() instanceof UDP) {
- UDP udp = (UDP)ipv4.getPayload();
- if (udp.getPayload() instanceof DHCP) {
- DHCP dhcp = (DHCP)udp.getPayload();
- if (dhcp.getOpCode() == DHCP.OPCODE_REPLY) {
- return ipv4.getSourceAddress();
- }
- }
- }
- }
- return 0;
- }
-
- /**
- * Parse an entity from an {@link Ethernet} packet.
- * @param eth the packet to parse
- * @param sw the switch on which the packet arrived
- * @param pi the original packetin
- * @return the entity from the packet
- */
- protected Entity getSourceEntityFromPacket(Ethernet eth,
- long swdpid,
- int port) {
- byte[] dlAddrArr = eth.getSourceMACAddress();
- long dlAddr = Ethernet.toLong(dlAddrArr);
-
- // Ignore broadcast/multicast source
- if ((dlAddrArr[0] & 0x1) != 0)
- return null;
-
- short vlan = eth.getVlanID();
- int nwSrc = getSrcNwAddr(eth, dlAddr);
- return new Entity(dlAddr,
- ((vlan >= 0) ? vlan : null),
- ((nwSrc != 0) ? nwSrc : null),
- swdpid,
- port,
- new Date());
- }
-
- /**
- * Get a (partial) entity for the destination from the packet.
- * @param eth
- * @return
- */
- protected Entity getDestEntityFromPacket(Ethernet eth) {
- byte[] dlAddrArr = eth.getDestinationMACAddress();
- long dlAddr = Ethernet.toLong(dlAddrArr);
- short vlan = eth.getVlanID();
- int nwDst = 0;
-
- // Ignore broadcast/multicast destination
- if ((dlAddrArr[0] & 0x1) != 0)
- return null;
-
- if (eth.getPayload() instanceof IPv4) {
- IPv4 ipv4 = (IPv4) eth.getPayload();
- nwDst = ipv4.getDestinationAddress();
- }
-
- return new Entity(dlAddr,
- ((vlan >= 0) ? vlan : null),
- ((nwDst != 0) ? nwDst : null),
- null,
- null,
- null);
- }
-
- /**
- * Parse an entity from an OFMatchWithSwDpid.
- * @param ofmWithSwDpid
- * @return the entity from the packet
- */
- private Entity getEntityFromFlowMod(OFMatchWithSwDpid ofmWithSwDpid,
- boolean isSource) {
- byte[] dlAddrArr = ofmWithSwDpid.getOfMatch().getDataLayerSource();
- int nwSrc = ofmWithSwDpid.getOfMatch().getNetworkSource();
- if (!isSource) {
- dlAddrArr = ofmWithSwDpid.getOfMatch().getDataLayerDestination();
- nwSrc = ofmWithSwDpid.getOfMatch().getNetworkDestination();
- }
-
- long dlAddr = Ethernet.toLong(dlAddrArr);
-
- // Ignore broadcast/multicast source
- if ((dlAddrArr[0] & 0x1) != 0)
- return null;
-
- Long swDpid = null;
- Short inPort = null;
-
- if (isSource) {
- swDpid = ofmWithSwDpid.getSwitchDataPathId();
- inPort = ofmWithSwDpid.getOfMatch().getInputPort();
- }
-
- boolean learnap = true;
- if (swDpid == null ||
- inPort == null ||
- !isValidAttachmentPoint(swDpid, inPort)) {
- // If this is an internal port or we otherwise don't want
- // to learn on these ports. In the future, we should
- // handle this case by labeling flows with something that
- // will give us the entity class. For now, we'll do our
- // best assuming attachment point information isn't used
- // as a key field.
- learnap = false;
- }
-
- short vlan = ofmWithSwDpid.getOfMatch().getDataLayerVirtualLan();
- return new Entity(dlAddr,
- ((vlan >= 0) ? vlan : null),
- ((nwSrc != 0) ? nwSrc : null),
- (learnap ? swDpid : null),
- (learnap ? (int)inPort : null),
- new Date());
- }
- /**
- * Look up a {@link Device} based on the provided {@link Entity}. We first
- * check the primary index. If we do not find an entry there we classify
- * the device into its IEntityClass and query the classIndex.
- * This implies that all key field of the current IEntityClassifier must
- * be present in the entity for the lookup to succeed!
- * @param entity the entity to search for
- * @return The {@link Device} object if found
- */
- protected Device findDeviceByEntity(Entity entity) {
- // Look up the fully-qualified entity to see if it already
- // exists in the primary entity index.
- Long deviceKey = primaryIndex.findByEntity(entity);
- IEntityClass entityClass = null;
-
- if (deviceKey == null) {
- // If the entity does not exist in the primary entity index,
- // use the entity classifier for find the classes for the
- // entity. Look up the entity in the returned class'
- // class entity index.
- entityClass = entityClassifier.classifyEntity(entity);
- if (entityClass == null) {
- return null;
- }
- ClassState classState = getClassState(entityClass);
-
- if (classState.classIndex != null) {
- deviceKey =
- classState.classIndex.findByEntity(entity);
- }
- }
- if (deviceKey == null) return null;
- return deviceMap.get(deviceKey);
- }
-
- /**
- * Get a destination device using entity fields that corresponds with
- * the given source device. The source device is important since
- * there could be ambiguity in the destination device without the
- * attachment point information.
- * @param source the source device. The returned destination will be
- * in the same entity class as the source.
- * @param dstEntity the entity to look up
- * @return an {@link Device} or null if no device is found.
- */
- protected Device findDestByEntity(IDevice source,
- Entity dstEntity) {
-
- // Look up the fully-qualified entity to see if it
- // exists in the primary entity index
- Long deviceKey = primaryIndex.findByEntity(dstEntity);
-
- if (deviceKey == null) {
- // This could happen because:
- // 1) no destination known, or a broadcast destination
- // 2) if we have attachment point key fields since
- // attachment point information isn't available for
- // destination devices.
- // For the second case, we'll need to match up the
- // destination device with the class of the source
- // device.
- ClassState classState = getClassState(source.getEntityClass());
- if (classState.classIndex == null) {
- return null;
- }
- deviceKey = classState.classIndex.findByEntity(dstEntity);
- }
- if (deviceKey == null) return null;
- return deviceMap.get(deviceKey);
- }
-
-
- /**
- * Look up a {@link Device} within a particular entity class based on
- * the provided {@link Entity}.
- * @param clazz the entity class to search for the entity
- * @param entity the entity to search for
- * @return The {@link Device} object if found
- private Device findDeviceInClassByEntity(IEntityClass clazz,
- Entity entity) {
- // XXX - TODO
- throw new UnsupportedOperationException();
- }
- */
-
- /**
- * Look up a {@link Device} based on the provided {@link Entity}. Also
- * learns based on the new entity, and will update existing devices as
- * required.
- *
- * @param entity the {@link Entity}
- * @return The {@link Device} object if found
- */
- protected Device learnDeviceByEntity(Entity entity) {
- ArrayList<Long> deleteQueue = null;
- LinkedList<DeviceUpdate> deviceUpdates = null;
- Device device = null;
-
- // we may need to restart the learning process if we detect
- // concurrent modification. Note that we ensure that at least
- // one thread should always succeed so we don't get into infinite
- // starvation loops
- while (true) {
- deviceUpdates = null;
-
- // Look up the fully-qualified entity to see if it already
- // exists in the primary entity index.
- Long deviceKey = primaryIndex.findByEntity(entity);
- IEntityClass entityClass = null;
-
- if (deviceKey == null) {
- // If the entity does not exist in the primary entity index,
- // use the entity classifier for find the classes for the
- // entity. Look up the entity in the returned class'
- // class entity index.
- entityClass = entityClassifier.classifyEntity(entity);
- if (entityClass == null) {
- // could not classify entity. No device
- return null;
- }
- ClassState classState = getClassState(entityClass);
-
- if (classState.classIndex != null) {
- deviceKey =
- classState.classIndex.findByEntity(entity);
- }
- }
- if (deviceKey != null) {
- // If the primary or secondary index contains the entity
- // use resulting device key to look up the device in the
- // device map, and use the referenced Device below.
- device = deviceMap.get(deviceKey);
- if (device == null)
- throw new IllegalStateException("Corrupted device index");
- } else {
- // If the secondary index does not contain the entity,
- // create a new Device object containing the entity, and
- // generate a new device ID. However, we first check if
- // the entity is allowed (e.g., for spoofing protection)
- if (!isEntityAllowed(entity, entityClass)) {
- logger.info("PacketIn is not allowed {} {}",
- entityClass.getName(), entity);
- return null;
- }
- synchronized (deviceKeyLock) {
- deviceKey = Long.valueOf(deviceKeyCounter++);
- }
- device = allocateDevice(deviceKey, entity, entityClass);
- if (logger.isDebugEnabled()) {
- logger.debug("New device created: {} deviceKey={}, entity={}",
- new Object[]{device, deviceKey, entity});
- }
-
- // Add the new device to the primary map with a simple put
- deviceMap.put(deviceKey, device);
-
- // update indices
- if (!updateIndices(device, deviceKey)) {
- if (deleteQueue == null)
- deleteQueue = new ArrayList<Long>();
- deleteQueue.add(deviceKey);
- continue;
- }
-
- updateSecondaryIndices(entity, entityClass, deviceKey);
-
- // generate new device update
- deviceUpdates =
- updateUpdates(deviceUpdates,
- new DeviceUpdate(device, DeviceUpdateType.ADD, null));
-
- break;
- }
-
- if (!isEntityAllowed(entity, device.getEntityClass())) {
- logger.info("PacketIn is not allowed {} {}",
- device.getEntityClass().getName(), entity);
- return null;
- }
- int entityindex = -1;
- if ((entityindex = device.entityIndex(entity)) >= 0) {
- // update timestamp on the found entity
- Date lastSeen = entity.getLastSeenTimestamp();
- if (lastSeen == null) lastSeen = new Date();
- device.entities[entityindex].setLastSeenTimestamp(lastSeen);
- if (device.entities[entityindex].getSwitchDPID() != null &&
- device.entities[entityindex].getSwitchPort() != null) {
- long sw = device.entities[entityindex].getSwitchDPID();
- short port = device.entities[entityindex].getSwitchPort().shortValue();
-
- boolean moved =
- device.updateAttachmentPoint(sw,
- port,
- lastSeen.getTime());
-
- if (moved) {
- sendDeviceMovedNotification(device);
- if (logger.isTraceEnabled()) {
- logger.trace("Device moved: attachment points {}," +
- "entities {}", device.attachmentPoints,
- device.entities);
- }
- } else {
- if (logger.isTraceEnabled()) {
- logger.trace("Device attachment point NOT updated: " +
- "attachment points {}," +
- "entities {}", device.attachmentPoints,
- device.entities);
- }
- }
- }
- break;
- } else {
- boolean moved = false;
- Device newDevice = allocateDevice(device, entity);
- if (entity.getSwitchDPID() != null && entity.getSwitchPort() != null) {
- moved = newDevice.updateAttachmentPoint(entity.getSwitchDPID(),
- entity.getSwitchPort().shortValue(),
- entity.getLastSeenTimestamp().getTime());
- }
-
- // generate updates
- EnumSet<DeviceField> changedFields =
- findChangedFields(device, entity);
- if (changedFields.size() > 0)
- deviceUpdates =
- updateUpdates(deviceUpdates,
- new DeviceUpdate(newDevice, DeviceUpdateType.CHANGE,
- changedFields));
-
- // update the device map with a replace call
- boolean res = deviceMap.replace(deviceKey, device, newDevice);
- // If replace returns false, restart the process from the
- // beginning (this implies another thread concurrently
- // modified this Device).
- if (!res)
- continue;
-
- device = newDevice;
-
- // update indices
- if (!updateIndices(device, deviceKey)) {
- continue;
- }
- updateSecondaryIndices(entity,
- device.getEntityClass(),
- deviceKey);
-
- if (moved) {
- sendDeviceMovedNotification(device);
- if (logger.isDebugEnabled()) {
- logger.debug("Device moved: attachment points {}," +
- "entities {}", device.attachmentPoints,
- device.entities);
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Device attachment point updated: " +
- "attachment points {}," +
- "entities {}", device.attachmentPoints,
- device.entities);
- }
- }
- break;
- }
- }
-
- if (deleteQueue != null) {
- for (Long l : deleteQueue) {
- Device dev = deviceMap.get(l);
- this.deleteDevice(dev);
-
-
- // generate new device update
- deviceUpdates =
- updateUpdates(deviceUpdates,
- new DeviceUpdate(dev, DeviceUpdateType.DELETE, null));
- }
- }
-
- processUpdates(deviceUpdates);
-
- return device;
- }
-
- protected boolean isEntityAllowed(Entity entity, IEntityClass entityClass) {
- return true;
- }
-
- protected EnumSet<DeviceField> findChangedFields(Device device,
- Entity newEntity) {
- EnumSet<DeviceField> changedFields =
- EnumSet.of(DeviceField.IPV4,
- DeviceField.VLAN,
- DeviceField.SWITCH);
-
- if (newEntity.getIpv4Address() == null)
- changedFields.remove(DeviceField.IPV4);
- if (newEntity.getVlan() == null)
- changedFields.remove(DeviceField.VLAN);
- if (newEntity.getSwitchDPID() == null ||
- newEntity.getSwitchPort() == null)
- changedFields.remove(DeviceField.SWITCH);
-
- if (changedFields.size() == 0) return changedFields;
-
- for (Entity entity : device.getEntities()) {
- if (newEntity.getIpv4Address() == null ||
- (entity.getIpv4Address() != null &&
- entity.getIpv4Address().equals(newEntity.getIpv4Address())))
- changedFields.remove(DeviceField.IPV4);
- if (newEntity.getVlan() == null ||
- (entity.getVlan() != null &&
- entity.getVlan().equals(newEntity.getVlan())))
- changedFields.remove(DeviceField.VLAN);
- if (newEntity.getSwitchDPID() == null ||
- newEntity.getSwitchPort() == null ||
- (entity.getSwitchDPID() != null &&
- entity.getSwitchPort() != null &&
- entity.getSwitchDPID().equals(newEntity.getSwitchDPID()) &&
- entity.getSwitchPort().equals(newEntity.getSwitchPort())))
- changedFields.remove(DeviceField.SWITCH);
- }
-
- return changedFields;
- }
-
- /**
- * Send update notifications to listeners
- * @param updates the updates to process.
- */
- protected void processUpdates(Queue<DeviceUpdate> updates) {
- if (updates == null) {
- return;
- }
-
- DeviceUpdate update;
- while (null != (update = updates.poll())) {
- floodlightProvider.publishUpdate(update);
- }
- /*
- if (updates == null) return;
- DeviceUpdate update = null;
- while (null != (update = updates.poll())) {
- if (logger.isTraceEnabled()) {
- logger.trace("Dispatching device update: {}", update);
- }
- for (IDeviceListener listener : deviceListeners) {
- switch (update.change) {
- case ADD:
- listener.deviceAdded(update.device);
- break;
- case DELETE:
- listener.deviceRemoved(update.device);
- break;
- case CHANGE:
- for (DeviceField field : update.fieldsChanged) {
- switch (field) {
- case IPV4:
- listener.deviceIPV4AddrChanged(update.device);
- break;
- case SWITCH:
- case PORT:
- //listener.deviceMoved(update.device);
- break;
- case VLAN:
- listener.deviceVlanChanged(update.device);
- break;
- default:
- logger.debug("Unknown device field changed {}",
- update.fieldsChanged.toString());
- break;
- }
- }
- break;
- }
- }
- }
- */
- }
-
- /**
- * Check if the entity e has all the keyFields set. Returns false if not
- * @param e entity to check
- * @param keyFields the key fields to check e against
- * @return
- */
- protected boolean allKeyFieldsPresent(Entity e, EnumSet<DeviceField> keyFields) {
- for (DeviceField f : keyFields) {
- switch (f) {
- case MAC:
- // MAC address is always present
- break;
- case IPV4:
- if (e.ipv4Address == null) return false;
- break;
- case SWITCH:
- if (e.switchDPID == null) return false;
- break;
- case PORT:
- if (e.switchPort == null) return false;
- break;
- case VLAN:
- // FIXME: vlan==null is ambiguous: it can mean: not present
- // or untagged
- //if (e.vlan == null) return false;
- break;
- default:
- // we should never get here. unless somebody extended
- // DeviceFields
- throw new IllegalStateException();
- }
- }
- return true;
- }
-
- private LinkedList<DeviceUpdate>
- updateUpdates(LinkedList<DeviceUpdate> list, DeviceUpdate update) {
- if (update == null) return list;
- if (list == null)
- list = new LinkedList<DeviceUpdate>();
- list.add(update);
-
- return list;
- }
-
- /**
- * Get the secondary index for a class. Will return null if the
- * secondary index was created concurrently in another thread.
- * @param clazz the class for the index
- * @return
- */
- private ClassState getClassState(IEntityClass clazz) {
- ClassState classState = classStateMap.get(clazz.getName());
- if (classState != null) return classState;
-
- classState = new ClassState(clazz);
- ClassState r = classStateMap.putIfAbsent(clazz.getName(), classState);
- if (r != null) {
- // concurrent add
- return r;
- }
- return classState;
- }
-
- /**
- * Update both the primary and class indices for the provided device.
- * If the update fails because of an concurrent update, will return false.
- * @param device the device to update
- * @param deviceKey the device key for the device
- * @return true if the update succeeded, false otherwise.
- */
- private boolean updateIndices(Device device, Long deviceKey) {
- if (!primaryIndex.updateIndex(device, deviceKey)) {
- return false;
- }
- IEntityClass entityClass = device.getEntityClass();
- ClassState classState = getClassState(entityClass);
-
- if (classState.classIndex != null) {
- if (!classState.classIndex.updateIndex(device,
- deviceKey))
- return false;
- }
- return true;
- }
-
- /**
- * Update the secondary indices for the given entity and associated
- * entity classes
- * @param entity the entity to update
- * @param entityClass the entity class for the entity
- * @param deviceKey the device key to set up
- */
- private void updateSecondaryIndices(Entity entity,
- IEntityClass entityClass,
- Long deviceKey) {
- for (DeviceIndex index : secondaryIndexMap.values()) {
- index.updateIndex(entity, deviceKey);
- }
- ClassState state = getClassState(entityClass);
- for (DeviceIndex index : state.secondaryIndexMap.values()) {
- index.updateIndex(entity, deviceKey);
- }
- }
-
- // *********************
- // IEntityClassListener
- // *********************
- @Override
- public void entityClassChanged (Set<String> entityClassNames) {
- /* iterate through the devices, reclassify the devices that belong
- * to these entity class names
- */
- Iterator<Device> diter = deviceMap.values().iterator();
- while (diter.hasNext()) {
- Device d = diter.next();
- if (d.getEntityClass() == null ||
- entityClassNames.contains(d.getEntityClass().getName()))
- reclassifyDevice(d);
- }
- }
-
- /**
- * Clean up expired entities/devices
- */
- protected void cleanupEntities () {
-
- Calendar c = Calendar.getInstance();
- c.add(Calendar.MILLISECOND, -ENTITY_TIMEOUT);
- Date cutoff = c.getTime();
-
- ArrayList<Entity> toRemove = new ArrayList<Entity>();
- ArrayList<Entity> toKeep = new ArrayList<Entity>();
-
- Iterator<Device> diter = deviceMap.values().iterator();
- LinkedList<DeviceUpdate> deviceUpdates =
- new LinkedList<DeviceUpdate>();
-
- while (diter.hasNext()) {
- Device d = diter.next();
-
- while (true) {
- deviceUpdates.clear();
- toRemove.clear();
- toKeep.clear();
- for (Entity e : d.getEntities()) {
- if (e.getLastSeenTimestamp() != null &&
- 0 > e.getLastSeenTimestamp().compareTo(cutoff)) {
- // individual entity needs to be removed
- toRemove.add(e);
- } else {
- toKeep.add(e);
- }
- }
- if (toRemove.size() == 0) {
- break;
- }
-
- for (Entity e : toRemove) {
- removeEntity(e, d.getEntityClass(), d.deviceKey, toKeep);
- }
-
- if (toKeep.size() > 0) {
- Device newDevice = allocateDevice(d.getDeviceKey(),
- d.oldAPs,
- d.attachmentPoints,
- toKeep,
- d.entityClass);
-
- EnumSet<DeviceField> changedFields =
- EnumSet.noneOf(DeviceField.class);
- for (Entity e : toRemove) {
- changedFields.addAll(findChangedFields(newDevice, e));
- }
- if (changedFields.size() > 0)
- deviceUpdates.add(new DeviceUpdate(d, DeviceUpdateType.CHANGE,
- changedFields));
-
- if (!deviceMap.replace(newDevice.getDeviceKey(),
- d,
- newDevice)) {
- // concurrent modification; try again
- // need to use device that is the map now for the next
- // iteration
- d = deviceMap.get(d.getDeviceKey());
- if (null != d)
- continue;
- }
- } else {
- deviceUpdates.add(new DeviceUpdate(d, DeviceUpdateType.DELETE, null));
- if (!deviceMap.remove(d.getDeviceKey(), d))
- // concurrent modification; try again
- // need to use device that is the map now for the next
- // iteration
- d = deviceMap.get(d.getDeviceKey());
- if (null != d)
- continue;
- }
- processUpdates(deviceUpdates);
- break;
- }
- }
- }
-
- protected void removeEntity(Entity removed,
- IEntityClass entityClass,
- Long deviceKey,
- Collection<Entity> others) {
- for (DeviceIndex index : secondaryIndexMap.values()) {
- index.removeEntityIfNeeded(removed, deviceKey, others);
- }
- ClassState classState = getClassState(entityClass);
- for (DeviceIndex index : classState.secondaryIndexMap.values()) {
- index.removeEntityIfNeeded(removed, deviceKey, others);
- }
-
- primaryIndex.removeEntityIfNeeded(removed, deviceKey, others);
-
- if (classState.classIndex != null) {
- classState.classIndex.removeEntityIfNeeded(removed,
- deviceKey,
- others);
- }
- }
-
- /**
- * method to delete a given device, remove all entities first and then
- * finally delete the device itself.
- * @param device
- */
- protected void deleteDevice(Device device) {
- ArrayList<Entity> emptyToKeep = new ArrayList<Entity>();
- for (Entity entity : device.getEntities()) {
- this.removeEntity(entity, device.getEntityClass(),
- device.getDeviceKey(), emptyToKeep);
- }
- if (!deviceMap.remove(device.getDeviceKey(), device)) {
- if (logger.isDebugEnabled())
- logger.debug("device map does not have this device -" +
- device.toString());
- }
- }
-
- private EnumSet<DeviceField> getEntityKeys(Long macAddress,
- Short vlan,
- Integer ipv4Address,
- Long switchDPID,
- Integer switchPort) {
- // FIXME: vlan==null is a valid search. Need to handle this
- // case correctly. Note that the code will still work correctly.
- // But we might do a full device search instead of using an index.
- EnumSet<DeviceField> keys = EnumSet.noneOf(DeviceField.class);
- if (macAddress != null) keys.add(DeviceField.MAC);
- if (vlan != null) keys.add(DeviceField.VLAN);
- if (ipv4Address != null) keys.add(DeviceField.IPV4);
- if (switchDPID != null) keys.add(DeviceField.SWITCH);
- if (switchPort != null) keys.add(DeviceField.PORT);
- return keys;
- }
-
-
- protected Iterator<Device> queryClassByEntity(IEntityClass clazz,
- EnumSet<DeviceField> keyFields,
- Entity entity) {
- ClassState classState = getClassState(clazz);
- DeviceIndex index = classState.secondaryIndexMap.get(keyFields);
- if (index == null) return Collections.<Device>emptySet().iterator();
- return new DeviceIndexInterator(this, index.queryByEntity(entity));
- }
-
- protected Device allocateDevice(Long deviceKey,
- Entity entity,
- IEntityClass entityClass) {
- return new Device(this, deviceKey, entity, entityClass);
- }
-
- // TODO: FIX THIS.
- protected Device allocateDevice(Long deviceKey,
- List<AttachmentPoint> aps,
- List<AttachmentPoint> trueAPs,
- Collection<Entity> entities,
- IEntityClass entityClass) {
- return new Device(this, deviceKey, aps, trueAPs, entities, entityClass);
- }
-
- protected Device allocateDevice(Device device,
- Entity entity) {
- return new Device(device, entity);
- }
-
- protected Device allocateDevice(Device device, Set <Entity> entities) {
- List <AttachmentPoint> newPossibleAPs =
- new ArrayList<AttachmentPoint>();
- List <AttachmentPoint> newAPs =
- new ArrayList<AttachmentPoint>();
- for (Entity entity : entities) {
- if (entity.switchDPID != null && entity.switchPort != null) {
- AttachmentPoint aP =
- new AttachmentPoint(entity.switchDPID.longValue(),
- entity.switchPort.shortValue(), 0);
- newPossibleAPs.add(aP);
- }
- }
- if (device.attachmentPoints != null) {
- for (AttachmentPoint oldAP : device.attachmentPoints) {
- if (newPossibleAPs.contains(oldAP)) {
- newAPs.add(oldAP);
- }
- }
- }
- if (newAPs.isEmpty())
- newAPs = null;
- Device d = new Device(this, device.getDeviceKey(),newAPs, null,
- entities, device.getEntityClass());
- d.updateAttachmentPoint();
- return d;
- }
-
- @Override
- public void addSuppressAPs(long swId, short port) {
- suppressAPs.add(new SwitchPort(swId, port));
- }
-
- @Override
- public void removeSuppressAPs(long swId, short port) {
- suppressAPs.remove(new SwitchPort(swId, port));
- }
-
- /**
- * Topology listener method.
- */
- @Override
- public void topologyChanged() {
- Iterator<Device> diter = deviceMap.values().iterator();
- List<LDUpdate> updateList = topology.getLastLinkUpdates();
- if (updateList != null) {
- if (logger.isTraceEnabled()) {
- for(LDUpdate update: updateList) {
- logger.trace("Topo update: {}", update);
- }
- }
- }
-
- while (diter.hasNext()) {
- Device d = diter.next();
- if (d.updateAttachmentPoint()) {
- if (logger.isDebugEnabled()) {
- logger.debug("Attachment point changed for device: {}", d);
- }
- sendDeviceMovedNotification(d);
- }
- }
- }
-
- /**
- * Send update notifications to listeners
- * @param updates the updates to process.
- */
- protected void sendDeviceMovedNotification(Device d) {
- /*for (IDeviceListener listener : deviceListeners) {
- listener.deviceMoved(d);
- }*/
- floodlightProvider.publishUpdate(
- new DeviceUpdate(d, DeviceUpdateType.MOVED, null));
- }
-
- /**
- * this method will reclassify and reconcile a device - possibilities
- * are - create new device(s), remove entities from this device. If the
- * device entity class did not change then it returns false else true.
- * @param device
- */
- protected boolean reclassifyDevice(Device device)
- {
- // first classify all entities of this device
- if (device == null) {
- logger.debug("In reclassify for null device");
- return false;
- }
- boolean needToReclassify = false;
- for (Entity entity : device.entities) {
- IEntityClass entityClass =
- this.entityClassifier.classifyEntity(entity);
- if (entityClass == null || device.getEntityClass() == null) {
- needToReclassify = true;
- break;
- }
- if (!entityClass.getName().
- equals(device.getEntityClass().getName())) {
- needToReclassify = true;
- break;
- }
- }
- if (needToReclassify == false) {
- return false;
- }
-
- LinkedList<DeviceUpdate> deviceUpdates =
- new LinkedList<DeviceUpdate>();
- // delete this device and then re-learn all the entities
- this.deleteDevice(device);
- deviceUpdates.add(new DeviceUpdate(device, DeviceUpdateType.DELETE, null));
- if (!deviceUpdates.isEmpty())
- processUpdates(deviceUpdates);
- for (Entity entity: device.entities ) {
- this.learnDeviceByEntity(entity);
- }
- return true;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceMultiIndex.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceMultiIndex.java
deleted file mode 100644
index c6aa980..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceMultiIndex.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
-* Copyright 2012 Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import net.floodlightcontroller.util.IterableIterator;
-
-/**
- * An index that maps key fields of an entity to device keys, with multiple
- * device keys allowed per entity
- */
-public class DeviceMultiIndex extends DeviceIndex {
- /**
- * The index
- */
- private ConcurrentHashMap<IndexedEntity, Collection<Long>> index;
-
- /**
- * @param keyFields
- */
- public DeviceMultiIndex(EnumSet<DeviceField> keyFields) {
- super(keyFields);
- index = new ConcurrentHashMap<IndexedEntity, Collection<Long>>();
- }
-
- // ***********
- // DeviceIndex
- // ***********
-
- @Override
- public Iterator<Long> queryByEntity(Entity entity) {
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- Collection<Long> devices = index.get(ie);
- if (devices != null)
- return devices.iterator();
-
- return Collections.<Long>emptySet().iterator();
- }
-
- @Override
- public Iterator<Long> getAll() {
- Iterator<Collection<Long>> iter = index.values().iterator();
- return new IterableIterator<Long>(iter);
- }
-
- @Override
- public boolean updateIndex(Device device, Long deviceKey) {
- for (Entity e : device.entities) {
- updateIndex(e, deviceKey);
- }
- return true;
- }
-
- @Override
- public void updateIndex(Entity entity, Long deviceKey) {
- Collection<Long> devices = null;
-
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- if (!ie.hasNonNullKeys()) return;
-
- devices = index.get(ie);
- if (devices == null) {
- Map<Long,Boolean> chm = new ConcurrentHashMap<Long,Boolean>();
- devices = Collections.newSetFromMap(chm);
- Collection<Long> r = index.putIfAbsent(ie, devices);
- if (r != null)
- devices = r;
- }
-
- devices.add(deviceKey);
- }
-
- @Override
- public void removeEntity(Entity entity) {
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- index.remove(ie);
- }
-
- @Override
- public void removeEntity(Entity entity, Long deviceKey) {
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- Collection<Long> devices = index.get(ie);
- if (devices != null)
- devices.remove(deviceKey);
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndex.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndex.java
deleted file mode 100644
index 4f2d3f8..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndex.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
-* Copyright 2012 Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
-
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-
-/**
- * An index that maps key fields of an entity uniquely to a device key
- */
-public class DeviceUniqueIndex extends DeviceIndex {
- /**
- * The index
- */
- private ConcurrentHashMap<IndexedEntity, Long> index;
-
- /**
- * Construct a new device index using the provided key fields
- * @param keyFields the key fields to use
- */
- public DeviceUniqueIndex(EnumSet<DeviceField> keyFields) {
- super(keyFields);
- index = new ConcurrentHashMap<IndexedEntity, Long>();
- }
-
- // ***********
- // DeviceIndex
- // ***********
-
- @Override
- public Iterator<Long> queryByEntity(Entity entity) {
- final Long deviceKey = findByEntity(entity);
- if (deviceKey != null)
- return Collections.<Long>singleton(deviceKey).iterator();
-
- return Collections.<Long>emptySet().iterator();
- }
-
- @Override
- public Iterator<Long> getAll() {
- return index.values().iterator();
- }
-
- @Override
- public boolean updateIndex(Device device, Long deviceKey) {
- for (Entity e : device.entities) {
- IndexedEntity ie = new IndexedEntity(keyFields, e);
- if (!ie.hasNonNullKeys()) continue;
-
- Long ret = index.putIfAbsent(ie, deviceKey);
- if (ret != null && !ret.equals(deviceKey)) {
- // If the return value is non-null, then fail the insert
- // (this implies that a device using this entity has
- // already been created in another thread).
- return false;
- }
- }
- return true;
- }
-
- @Override
- public void updateIndex(Entity entity, Long deviceKey) {
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- if (!ie.hasNonNullKeys()) return;
- index.put(ie, deviceKey);
- }
-
- @Override
- public void removeEntity(Entity entity) {
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- index.remove(ie);
- }
-
- @Override
- public void removeEntity(Entity entity, Long deviceKey) {
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- index.remove(ie, deviceKey);
- }
-
- // **************
- // Public Methods
- // **************
-
- /**
- * Look up a {@link Device} based on the provided {@link Entity}.
- * @param entity the entity to search for
- * @return The key for the {@link Device} object if found
- */
- public Long findByEntity(Entity entity) {
- IndexedEntity ie = new IndexedEntity(keyFields, entity);
- Long deviceKey = index.get(ie);
- if (deviceKey == null)
- return null;
- return deviceKey;
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/Entity.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/Entity.java
deleted file mode 100644
index 36c5471..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/Entity.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/**
-* Copyright 2011,2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.Date;
-
-import net.floodlightcontroller.core.web.serializers.IPv4Serializer;
-import net.floodlightcontroller.core.web.serializers.MACSerializer;
-import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
-import net.floodlightcontroller.packet.IPv4;
-
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-import org.openflow.util.HexString;
-
-/**
- * An entity on the network is a visible trace of a device that corresponds
- * to a packet received from a particular interface on the edge of a network,
- * with a particular VLAN tag, and a particular MAC address, along with any
- * other packet characteristics we might want to consider as helpful for
- * disambiguating devices.
- *
- * Entities are the most basic element of devices; devices consist of one or
- * more entities. Entities are immutable once created, except for the last
- * seen timestamp.
- *
- * @author readams
- *
- */
-public class Entity implements Comparable<Entity> {
- /**
- * Timeout for computing {@link Entity#activeSince}.
- * @see {@link Entity#activeSince}
- */
- protected static int ACTIVITY_TIMEOUT = 30000;
-
- /**
- * The MAC address associated with this entity
- */
- protected long macAddress;
-
- /**
- * The IP address associated with this entity, or null if no IP learned
- * from the network observation associated with this entity
- */
- protected Integer ipv4Address;
-
- /**
- * The VLAN tag on this entity, or null if untagged
- */
- protected Short vlan;
-
- /**
- * The DPID of the switch for the ingress point for this entity,
- * or null if not present
- */
- protected Long switchDPID;
-
- /**
- * The port number of the switch for the ingress point for this entity,
- * or null if not present
- */
- protected Integer switchPort;
-
- /**
- * The last time we observed this entity on the network
- */
- protected Date lastSeenTimestamp;
-
- /**
- * The time between {@link Entity#activeSince} and
- * {@link Entity#lastSeenTimestamp} is a period of activity for this
- * entity where it was observed repeatedly. If, when the entity is
- * observed, the is longer ago than the activity timeout,
- * {@link Entity#lastSeenTimestamp} and {@link Entity#activeSince} will
- * be set to the current time.
- */
- protected Date activeSince;
-
- private int hashCode = 0;
-
- // ************
- // Constructors
- // ************
-
- /**
- * Create a new entity
- *
- * @param macAddress
- * @param vlan
- * @param ipv4Address
- * @param switchDPID
- * @param switchPort
- * @param lastSeenTimestamp
- */
- public Entity(long macAddress, Short vlan,
- Integer ipv4Address, Long switchDPID, Integer switchPort,
- Date lastSeenTimestamp) {
- this.macAddress = macAddress;
- this.ipv4Address = ipv4Address;
- this.vlan = vlan;
- this.switchDPID = switchDPID;
- this.switchPort = switchPort;
- this.lastSeenTimestamp = lastSeenTimestamp;
- this.activeSince = lastSeenTimestamp;
- }
-
- // ***************
- // Getters/Setters
- // ***************
-
- @JsonSerialize(using=MACSerializer.class)
- public long getMacAddress() {
- return macAddress;
- }
-
- @JsonSerialize(using=IPv4Serializer.class)
- public Integer getIpv4Address() {
- return ipv4Address;
- }
-
- public Short getVlan() {
- return vlan;
- }
-
- @JsonSerialize(using=DPIDSerializer.class)
- public Long getSwitchDPID() {
- return switchDPID;
- }
-
- public Integer getSwitchPort() {
- return switchPort;
- }
-
- public Date getLastSeenTimestamp() {
- return lastSeenTimestamp;
- }
-
- /**
- * Set the last seen timestamp and also update {@link Entity#activeSince}
- * if appropriate
- * @param lastSeenTimestamp the new last seen timestamp
- * @see {@link Entity#activeSince}
- */
- public void setLastSeenTimestamp(Date lastSeenTimestamp) {
- if (activeSince == null ||
- (activeSince.getTime() + ACTIVITY_TIMEOUT) <
- lastSeenTimestamp.getTime())
- this.activeSince = lastSeenTimestamp;
- this.lastSeenTimestamp = lastSeenTimestamp;
- }
-
- public Date getActiveSince() {
- return activeSince;
- }
-
- public void setActiveSince(Date activeSince) {
- this.activeSince = activeSince;
- }
-
- @Override
- public int hashCode() {
- if (hashCode != 0) return hashCode;
- final int prime = 31;
- hashCode = 1;
- hashCode = prime * hashCode
- + ((ipv4Address == null) ? 0 : ipv4Address.hashCode());
- hashCode = prime * hashCode + (int) (macAddress ^ (macAddress >>> 32));
- hashCode = prime * hashCode
- + ((switchDPID == null) ? 0 : switchDPID.hashCode());
- hashCode = prime * hashCode
- + ((switchPort == null) ? 0 : switchPort.hashCode());
- hashCode = prime * hashCode + ((vlan == null) ? 0 : vlan.hashCode());
- return hashCode;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- Entity other = (Entity) obj;
- if (hashCode() != other.hashCode()) return false;
- if (ipv4Address == null) {
- if (other.ipv4Address != null) return false;
- } else if (!ipv4Address.equals(other.ipv4Address)) return false;
- if (macAddress != other.macAddress) return false;
- if (switchDPID == null) {
- if (other.switchDPID != null) return false;
- } else if (!switchDPID.equals(other.switchDPID)) return false;
- if (switchPort == null) {
- if (other.switchPort != null) return false;
- } else if (!switchPort.equals(other.switchPort)) return false;
- if (vlan == null) {
- if (other.vlan != null) return false;
- } else if (!vlan.equals(other.vlan)) return false;
- return true;
- }
-
-
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("Entity [macAddress=");
- builder.append(HexString.toHexString(macAddress, 6));
- builder.append(", ipv4Address=");
- builder.append(IPv4.fromIPv4Address(ipv4Address==null ?
- 0 : ipv4Address.intValue()));
- builder.append(", vlan=");
- builder.append(vlan);
- builder.append(", switchDPID=");
- builder.append(switchDPID);
- builder.append(", switchPort=");
- builder.append(switchPort);
- builder.append(", lastSeenTimestamp=");
- builder.append(lastSeenTimestamp == null? "null" : lastSeenTimestamp.getTime());
- builder.append(", activeSince=");
- builder.append(activeSince == null? "null" : activeSince.getTime());
- builder.append("]");
- return builder.toString();
- }
-
- @Override
- public int compareTo(Entity o) {
- if (macAddress < o.macAddress) return -1;
- if (macAddress > o.macAddress) return 1;
-
- int r;
- if (switchDPID == null)
- r = o.switchDPID == null ? 0 : -1;
- else if (o.switchDPID == null)
- r = 1;
- else
- r = switchDPID.compareTo(o.switchDPID);
- if (r != 0) return r;
-
- if (switchPort == null)
- r = o.switchPort == null ? 0 : -1;
- else if (o.switchPort == null)
- r = 1;
- else
- r = switchPort.compareTo(o.switchPort);
- if (r != 0) return r;
-
- if (ipv4Address == null)
- r = o.ipv4Address == null ? 0 : -1;
- else if (o.ipv4Address == null)
- r = 1;
- else
- r = ipv4Address.compareTo(o.ipv4Address);
- if (r != 0) return r;
-
- if (vlan == null)
- r = o.vlan == null ? 0 : -1;
- else if (o.vlan == null)
- r = 1;
- else
- r = vlan.compareTo(o.vlan);
- if (r != 0) return r;
-
- return 0;
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/IndexedEntity.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/IndexedEntity.java
deleted file mode 100644
index 3bb9bfa..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/IndexedEntity.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.EnumSet;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-
-
-/**
- * This is a thin wrapper around {@link Entity} that allows overriding
- * the behavior of {@link Object#hashCode()} and {@link Object#equals(Object)}
- * so that the keying behavior in a hash map can be changed dynamically
- * @author readams
- */
-public class IndexedEntity {
- protected EnumSet<DeviceField> keyFields;
- protected Entity entity;
- private int hashCode = 0;
- protected final static Logger logger =
- LoggerFactory.getLogger(IndexedEntity.class);
- /**
- * Create a new {@link IndexedEntity} for the given {@link Entity} using
- * the provided key fields.
- * @param keyFields The key fields that will be used for computing
- * {@link IndexedEntity#hashCode()} and {@link IndexedEntity#equals(Object)}
- * @param entity the entity to wrap
- */
- public IndexedEntity(EnumSet<DeviceField> keyFields, Entity entity) {
- super();
- this.keyFields = keyFields;
- this.entity = entity;
- }
-
- /**
- * Check whether this entity has non-null values in any of its key fields
- * @return true if any key fields have a non-null value
- */
- public boolean hasNonNullKeys() {
- for (DeviceField f : keyFields) {
- switch (f) {
- case MAC:
- return true;
- case IPV4:
- if (entity.ipv4Address != null) return true;
- break;
- case SWITCH:
- if (entity.switchDPID != null) return true;
- break;
- case PORT:
- if (entity.switchPort != null) return true;
- break;
- case VLAN:
- if (entity.vlan != null) return true;
- break;
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
-
- if (hashCode != 0) {
- return hashCode;
- }
-
- final int prime = 31;
- hashCode = 1;
- for (DeviceField f : keyFields) {
- switch (f) {
- case MAC:
- hashCode = prime * hashCode
- + (int) (entity.macAddress ^
- (entity.macAddress >>> 32));
- break;
- case IPV4:
- hashCode = prime * hashCode
- + ((entity.ipv4Address == null)
- ? 0
- : entity.ipv4Address.hashCode());
- break;
- case SWITCH:
- hashCode = prime * hashCode
- + ((entity.switchDPID == null)
- ? 0
- : entity.switchDPID.hashCode());
- break;
- case PORT:
- hashCode = prime * hashCode
- + ((entity.switchPort == null)
- ? 0
- : entity.switchPort.hashCode());
- break;
- case VLAN:
- hashCode = prime * hashCode
- + ((entity.vlan == null)
- ? 0
- : entity.vlan.hashCode());
- break;
- }
- }
- return hashCode;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- IndexedEntity other = (IndexedEntity) obj;
-
- if (!keyFields.equals(other.keyFields))
- return false;
-
- for (IDeviceService.DeviceField f : keyFields) {
- switch (f) {
- case MAC:
- if (entity.macAddress != other.entity.macAddress)
- return false;
- break;
- case IPV4:
- if (entity.ipv4Address == null) {
- if (other.entity.ipv4Address != null) return false;
- } else if (!entity.ipv4Address.
- equals(other.entity.ipv4Address)) return false;
- break;
- case SWITCH:
- if (entity.switchDPID == null) {
- if (other.entity.switchDPID != null) return false;
- } else if (!entity.switchDPID.
- equals(other.entity.switchDPID)) return false;
- break;
- case PORT:
- if (entity.switchPort == null) {
- if (other.entity.switchPort != null) return false;
- } else if (!entity.switchPort.
- equals(other.entity.switchPort)) return false;
- break;
- case VLAN:
- if (entity.vlan == null) {
- if (other.entity.vlan != null) return false;
- } else if (!entity.vlan.
- equals(other.entity.vlan)) return false;
- break;
- }
- }
-
- return true;
- }
-
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/AbstractDeviceResource.java b/src/main/java/net/floodlightcontroller/devicemanager/web/AbstractDeviceResource.java
deleted file mode 100644
index 58e79e4..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/web/AbstractDeviceResource.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/**
-* Copyright 2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.web;
-
-import java.util.Iterator;
-
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.devicemanager.internal.Device;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.util.FilterIterator;
-
-import org.openflow.util.HexString;
-import org.restlet.data.Form;
-import org.restlet.data.Status;
-import org.restlet.resource.ServerResource;
-
-/**
- * Resource for querying and displaying devices that exist in the system
- */
-public abstract class AbstractDeviceResource extends ServerResource {
- public static final String MAC_ERROR =
- "Invalid MAC address: must be a 48-bit quantity, " +
- "expressed in hex as AA:BB:CC:DD:EE:FF";
- public static final String VLAN_ERROR =
- "Invalid VLAN: must be an integer in the range 0-4095";
- public static final String IPV4_ERROR =
- "Invalid IPv4 address: must be in dotted decimal format, " +
- "234.0.59.1";
- public static final String DPID_ERROR =
- "Invalid Switch DPID: must be a 64-bit quantity, expressed in " +
- "hex as AA:BB:CC:DD:EE:FF:00:11";
- public static final String PORT_ERROR =
- "Invalid Port: must be a positive integer";
-
- public Iterator<? extends IDevice> getDevices() {
- IDeviceService deviceManager =
- (IDeviceService)getContext().getAttributes().
- get(IDeviceService.class.getCanonicalName());
-
- Long macAddress = null;
- Short vlan = null;
- Integer ipv4Address = null;
- Long switchDPID = null;
- Integer switchPort = null;
-
- Form form = getQuery();
- String macAddrStr = form.getFirstValue("mac", true);
- String vlanStr = form.getFirstValue("vlan", true);
- String ipv4Str = form.getFirstValue("ipv4", true);
- String dpid = form.getFirstValue("dpid", true);
- String port = form.getFirstValue("port", true);
-
- if (macAddrStr != null) {
- try {
- macAddress = HexString.toLong(macAddrStr);
- } catch (Exception e) {
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST, MAC_ERROR);
- return null;
- }
- }
- if (vlanStr != null) {
- try {
- vlan = Short.parseShort(vlanStr);
- if (vlan > 4095 || vlan < 0) {
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST, VLAN_ERROR);
- return null;
- }
- } catch (Exception e) {
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST, VLAN_ERROR);
- return null;
- }
- }
- if (ipv4Str != null) {
- try {
- ipv4Address = IPv4.toIPv4Address(ipv4Str);
- } catch (Exception e) {
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST, IPV4_ERROR);
- return null;
- }
- }
- if (dpid != null) {
- try {
- switchDPID = HexString.toLong(dpid);
- } catch (Exception e) {
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST, DPID_ERROR);
- return null;
- }
- }
- if (port != null) {
- try {
- switchPort = Integer.parseInt(port);
- if (switchPort < 0) {
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST, PORT_ERROR);
- return null;
- }
- } catch (Exception e) {
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST, PORT_ERROR);
- return null;
- }
- }
-
- @SuppressWarnings("unchecked")
- Iterator<Device> diter = (Iterator<Device>)
- deviceManager.queryDevices(macAddress,
- vlan,
- ipv4Address,
- switchDPID,
- switchPort);
-
- final String macStartsWith =
- form.getFirstValue("mac__startswith", true);
- final String vlanStartsWith =
- form.getFirstValue("vlan__startswith", true);
- final String ipv4StartsWith =
- form.getFirstValue("ipv4__startswith", true);
- final String dpidStartsWith =
- form.getFirstValue("dpid__startswith", true);
- final String portStartsWith =
- form.getFirstValue("port__startswith", true);
-
- return new FilterIterator<Device>(diter) {
- @Override
- protected boolean matches(Device value) {
- if (macStartsWith != null) {
- if (!value.getMACAddressString().startsWith(macStartsWith))
- return false;
- }
- if (vlanStartsWith != null) {
- boolean match = false;
- for (Short v : value.getVlanId()) {
- if (v != null &&
- v.toString().startsWith(vlanStartsWith)) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
- if (ipv4StartsWith != null) {
- boolean match = false;
- for (Integer v : value.getIPv4Addresses()) {
- String str = IPv4.fromIPv4Address(v);
- if (v != null &&
- str.startsWith(ipv4StartsWith)) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
- if (dpidStartsWith != null) {
- boolean match = false;
- for (SwitchPort v : value.getAttachmentPoints(true)) {
- String str =
- HexString.toHexString(v.getSwitchDPID(), 8);
- if (v != null &&
- str.startsWith(dpidStartsWith)) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
- if (portStartsWith != null) {
- boolean match = false;
- for (SwitchPort v : value.getAttachmentPoints(true)) {
- String str = Integer.toString(v.getPort());
- if (v != null &&
- str.startsWith(portStartsWith)) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
- return true;
- }
- };
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceEntityResource.java b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceEntityResource.java
deleted file mode 100644
index 2783a26..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceEntityResource.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
-* Copyright 2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.web;
-
-import java.util.Iterator;
-
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.internal.Device;
-import net.floodlightcontroller.devicemanager.internal.Entity;
-
-import org.restlet.resource.Get;
-
-/**
- * Resource for querying and displaying internal debug information on
- * network entities associated with devices
- */
-public class DeviceEntityResource extends AbstractDeviceResource {
- @Get("json")
- public Iterator<Entity[]> getDeviceEntities() {
- final Iterator<? extends IDevice> devices = super.getDevices();
- return new Iterator<Entity[]>() {
-
- @Override
- public boolean hasNext() {
- return devices.hasNext();
- }
-
- @Override
- public Entity[] next() {
- Device d = (Device)devices.next();
- return d.getEntities();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceResource.java b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceResource.java
deleted file mode 100644
index c479af0..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceResource.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
-* Copyright 2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.web;
-
-import java.util.Iterator;
-
-import net.floodlightcontroller.devicemanager.IDevice;
-import org.restlet.resource.Get;
-
-/**
- * Resource for querying and displaying devices that exist in the system
- */
-public class DeviceResource extends AbstractDeviceResource {
- @Get("json")
- public Iterator<? extends IDevice> getDevices() {
- return super.getDevices();
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceRoutable.java b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceRoutable.java
deleted file mode 100644
index 3648569..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceRoutable.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
-* Copyright 2012, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.web;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-/**
- * Routable for device rest api
- */
-public class DeviceRoutable implements RestletRoutable {
-
- @Override
- public String basePath() {
- return "/wm/floodlight/device";
- }
-
- @Override
- public Restlet getRestlet(Context context) {
- Router router = new Router(context);
- router.attach("/", DeviceResource.class);
- router.attach("/debug", DeviceEntityResource.class);
- return router;
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java
deleted file mode 100644
index 66bdaef..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
-* Copyright 2012 Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.web;
-
-import java.io.IOException;
-
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.devicemanager.internal.Device;
-import net.floodlightcontroller.packet.IPv4;
-
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.map.JsonSerializer;
-import org.codehaus.jackson.map.SerializerProvider;
-import org.openflow.util.HexString;
-
-/**
- * Serialize a device object
- */
-public class DeviceSerializer extends JsonSerializer<Device> {
-
- @Override
- public void serialize(Device device, JsonGenerator jGen,
- SerializerProvider serializer) throws IOException,
- JsonProcessingException {
- jGen.writeStartObject();
-
- jGen.writeStringField("entityClass", device.getEntityClass().getName());
-
- jGen.writeArrayFieldStart("mac");
- jGen.writeString(HexString.toHexString(device.getMACAddress(), 6));
- jGen.writeEndArray();
-
- jGen.writeArrayFieldStart("ipv4");
- for (Integer ip : device.getIPv4Addresses())
- jGen.writeString(IPv4.fromIPv4Address(ip));
- jGen.writeEndArray();
-
- jGen.writeArrayFieldStart("vlan");
- for (Short vlan : device.getVlanId())
- if (vlan >= 0)
- jGen.writeNumber(vlan);
- jGen.writeEndArray();
- jGen.writeArrayFieldStart("attachmentPoint");
- for (SwitchPort ap : device.getAttachmentPoints(true)) {
- serializer.defaultSerializeValue(ap, jGen);
- }
- jGen.writeEndArray();
-
- jGen.writeNumberField("lastSeen", device.getLastSeen().getTime());
-
- jGen.writeEndObject();
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
deleted file mode 100644
index a245c02..0000000
--- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.forwarding;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.annotations.LogMessageDocs;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.routing.ForwardingBase;
-import net.floodlightcontroller.routing.IRoutingDecision;
-import net.floodlightcontroller.routing.IRoutingService;
-import net.floodlightcontroller.routing.Route;
-import net.floodlightcontroller.topology.ITopologyService;
-
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@LogMessageCategory("Flow Programming")
-public class Forwarding extends ForwardingBase implements IFloodlightModule {
- protected final static Logger log = LoggerFactory.getLogger(Forwarding.class);
-
- @Override
- @LogMessageDoc(level="ERROR",
- message="Unexpected decision made for this packet-in={}",
- explanation="An unsupported PacketIn decision has been " +
- "passed to the flow programming component",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
- public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision,
- FloodlightContext cntx) {
- Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
- // If a decision has been made we obey it
- // otherwise we just forward
- if (decision != null) {
- if (log.isTraceEnabled()) {
- log.trace("Forwaring decision={} was made for PacketIn={}",
- decision.getRoutingAction().toString(),
- pi);
- }
-
- switch(decision.getRoutingAction()) {
- case NONE:
- // don't do anything
- return Command.CONTINUE;
- case FORWARD_OR_FLOOD:
- case FORWARD:
- doForwardFlow(sw, pi, cntx, false);
- return Command.CONTINUE;
- case MULTICAST:
- // treat as broadcast
- doFlood(sw, pi, cntx);
- return Command.CONTINUE;
- case DROP:
- doDropFlow(sw, pi, decision, cntx);
- return Command.CONTINUE;
- default:
- log.error("Unexpected decision made for this packet-in={}",
- pi, decision.getRoutingAction());
- return Command.CONTINUE;
- }
- } else {
- if (log.isTraceEnabled()) {
- log.trace("No decision was made for PacketIn={}, forwarding",
- pi);
- }
-
- if (eth.isBroadcast() || eth.isMulticast()) {
- // For now we treat multicast as broadcast
- doFlood(sw, pi, cntx);
- } else {
- doForwardFlow(sw, pi, cntx, false);
- }
- }
-
- return Command.CONTINUE;
- }
-
- @LogMessageDoc(level="ERROR",
- message="Failure writing drop flow mod",
- explanation="An I/O error occured while trying to write a " +
- "drop flow mod to a switch",
- recommendation=LogMessageDoc.CHECK_SWITCH)
- protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
- // initialize match structure and populate it using the packet
- OFMatch match = new OFMatch();
- match.loadFromPacket(pi.getPacketData(), pi.getInPort());
- if (decision.getWildcards() != null) {
- match.setWildcards(decision.getWildcards());
- }
-
- // Create flow-mod based on packet-in and src-switch
- OFFlowMod fm =
- (OFFlowMod) floodlightProvider.getOFMessageFactory()
- .getMessage(OFType.FLOW_MOD);
- List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to
- // drop
- long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);
-
- fm.setCookie(cookie)
- .setHardTimeout((short) 0)
- .setIdleTimeout((short) 5)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH);
-
- try {
- if (log.isDebugEnabled()) {
- log.debug("write drop flow-mod sw={} match={} flow-mod={}",
- new Object[] { sw, match, fm });
- }
- messageDamper.write(sw, fm, cntx);
- } catch (IOException e) {
- log.error("Failure writing drop flow mod", e);
- }
- }
-
- protected void doForwardFlow(IOFSwitch sw, OFPacketIn pi,
- FloodlightContext cntx,
- boolean requestFlowRemovedNotifn) {
- OFMatch match = new OFMatch();
- match.loadFromPacket(pi.getPacketData(), pi.getInPort());
-
- // Check if we have the location of the destination
- IDevice dstDevice =
- IDeviceService.fcStore.
- get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
-
- if (dstDevice != null) {
- IDevice srcDevice =
- IDeviceService.fcStore.
- get(cntx, IDeviceService.CONTEXT_SRC_DEVICE);
- Long srcIsland = topology.getL2DomainId(sw.getId());
-
- if (srcDevice == null) {
- log.debug("No device entry found for source device");
- return;
- }
- if (srcIsland == null) {
- log.debug("No openflow island found for source {}/{}",
- sw.getStringId(), pi.getInPort());
- return;
- }
-
- // Validate that we have a destination known on the same island
- // Validate that the source and destination are not on the same switchport
- boolean on_same_island = false;
- boolean on_same_if = false;
- for (SwitchPort dstDap : dstDevice.getAttachmentPoints()) {
- long dstSwDpid = dstDap.getSwitchDPID();
- Long dstIsland = topology.getL2DomainId(dstSwDpid);
- if ((dstIsland != null) && dstIsland.equals(srcIsland)) {
- on_same_island = true;
- if ((sw.getId() == dstSwDpid) &&
- (pi.getInPort() == dstDap.getPort())) {
- on_same_if = true;
- }
- break;
- }
- }
-
- if (!on_same_island) {
- // Flood since we don't know the dst device
- if (log.isTraceEnabled()) {
- log.trace("No first hop island found for destination " +
- "device {}, Action = flooding", dstDevice);
- }
- doFlood(sw, pi, cntx);
- return;
- }
-
- if (on_same_if) {
- if (log.isTraceEnabled()) {
- log.trace("Both source and destination are on the same " +
- "switch/port {}/{}, Action = NOP",
- sw.toString(), pi.getInPort());
- }
- return;
- }
-
- // Install all the routes where both src and dst have attachment
- // points. Since the lists are stored in sorted order we can
- // traverse the attachment points in O(m+n) time
- SwitchPort[] srcDaps = srcDevice.getAttachmentPoints();
- Arrays.sort(srcDaps, clusterIdComparator);
- SwitchPort[] dstDaps = dstDevice.getAttachmentPoints();
- Arrays.sort(dstDaps, clusterIdComparator);
-
- int iSrcDaps = 0, iDstDaps = 0;
-
- while ((iSrcDaps < srcDaps.length) && (iDstDaps < dstDaps.length)) {
- SwitchPort srcDap = srcDaps[iSrcDaps];
- SwitchPort dstDap = dstDaps[iDstDaps];
- Long srcCluster =
- topology.getL2DomainId(srcDap.getSwitchDPID());
- Long dstCluster =
- topology.getL2DomainId(dstDap.getSwitchDPID());
-
- int srcVsDest = srcCluster.compareTo(dstCluster);
- if (srcVsDest == 0) {
- if (!srcDap.equals(dstDap) &&
- (srcCluster != null) &&
- (dstCluster != null)) {
- Route route =
- routingEngine.getRoute(srcDap.getSwitchDPID(),
- (short)srcDap.getPort(),
- dstDap.getSwitchDPID(),
- (short)dstDap.getPort());
- if (route != null) {
- if (log.isTraceEnabled()) {
- log.trace("pushRoute match={} route={} " +
- "destination={}:{}",
- new Object[] {match, route,
- dstDap.getSwitchDPID(),
- dstDap.getPort()});
- }
- long cookie =
- AppCookie.makeCookie(FORWARDING_APP_ID, 0);
-
- // if there is prior routing decision use wildcard
- Integer wildcard_hints = null;
- IRoutingDecision decision = null;
- if (cntx != null) {
- decision = IRoutingDecision.rtStore
- .get(cntx,
- IRoutingDecision.CONTEXT_DECISION);
- }
- if (decision != null) {
- wildcard_hints = decision.getWildcards();
- } else {
- // L2 only wildcard if there is no prior route decision
- wildcard_hints = ((Integer) sw
- .getAttribute(IOFSwitch.PROP_FASTWILDCARDS))
- .intValue()
- & ~OFMatch.OFPFW_IN_PORT
- & ~OFMatch.OFPFW_DL_VLAN
- & ~OFMatch.OFPFW_DL_SRC
- & ~OFMatch.OFPFW_DL_DST
- & ~OFMatch.OFPFW_NW_SRC_MASK
- & ~OFMatch.OFPFW_NW_DST_MASK;
- }
-
- pushRoute(route, match, wildcard_hints, pi, sw.getId(), cookie,
- cntx, requestFlowRemovedNotifn, false,
- OFFlowMod.OFPFC_ADD);
- }
- }
- iSrcDaps++;
- iDstDaps++;
- } else if (srcVsDest < 0) {
- iSrcDaps++;
- } else {
- iDstDaps++;
- }
- }
- } else {
- // Flood since we don't know the dst device
- doFlood(sw, pi, cntx);
- }
- }
-
- /**
- * Creates a OFPacketOut with the OFPacketIn data that is flooded on all ports unless
- * the port is blocked, in which case the packet will be dropped.
- * @param sw The switch that receives the OFPacketIn
- * @param pi The OFPacketIn that came to the switch
- * @param cntx The FloodlightContext associated with this OFPacketIn
- */
- @LogMessageDoc(level="ERROR",
- message="Failure writing PacketOut " +
- "switch={switch} packet-in={packet-in} " +
- "packet-out={packet-out}",
- explanation="An I/O error occured while writing a packet " +
- "out message to the switch",
- recommendation=LogMessageDoc.CHECK_SWITCH)
- protected void doFlood(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
- if (topology.isIncomingBroadcastAllowed(sw.getId(),
- pi.getInPort()) == false) {
- if (log.isTraceEnabled()) {
- log.trace("doFlood, drop broadcast packet, pi={}, " +
- "from a blocked port, srcSwitch=[{},{}], linkInfo={}",
- new Object[] {pi, sw.getId(),pi.getInPort()});
- }
- return;
- }
-
- // Set Action to flood
- OFPacketOut po =
- (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
- List<OFAction> actions = new ArrayList<OFAction>();
- if (sw.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD)) {
- actions.add(new OFActionOutput(OFPort.OFPP_FLOOD.getValue(),
- (short)0xFFFF));
- } else {
- actions.add(new OFActionOutput(OFPort.OFPP_ALL.getValue(),
- (short)0xFFFF));
- }
- po.setActions(actions);
- po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
-
- // set buffer-id, in-port and packet-data based on packet-in
- short poLength = (short)(po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
- po.setBufferId(pi.getBufferId());
- po.setInPort(pi.getInPort());
- if (pi.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
- byte[] packetData = pi.getPacketData();
- poLength += packetData.length;
- po.setPacketData(packetData);
- }
- po.setLength(poLength);
-
- try {
- if (log.isTraceEnabled()) {
- log.trace("Writing flood PacketOut switch={} packet-in={} packet-out={}",
- new Object[] {sw, pi, po});
- }
- messageDamper.write(sw, po, cntx);
- } catch (IOException e) {
- log.error("Failure writing PacketOut switch={} packet-in={} packet-out={}",
- new Object[] {sw, pi, po}, e);
- }
-
- return;
- }
-
- // IFloodlightModule methods
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- // We don't export any services
- return null;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- // We don't have any services
- return null;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(IDeviceService.class);
- l.add(IRoutingService.class);
- l.add(ITopologyService.class);
- return l;
- }
-
- @Override
- @LogMessageDocs({
- @LogMessageDoc(level="WARN",
- message="Error parsing flow idle timeout, " +
- "using default of {number} seconds",
- explanation="The properties file contains an invalid " +
- "flow idle timeout",
- recommendation="Correct the idle timeout in the " +
- "properties file."),
- @LogMessageDoc(level="WARN",
- message="Error parsing flow hard timeout, " +
- "using default of {number} seconds",
- explanation="The properties file contains an invalid " +
- "flow hard timeout",
- recommendation="Correct the hard timeout in the " +
- "properties file.")
- })
- public void init(FloodlightModuleContext context) throws FloodlightModuleException {
- super.init();
- this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
- this.deviceManager = context.getServiceImpl(IDeviceService.class);
- this.routingEngine = context.getServiceImpl(IRoutingService.class);
- this.topology = context.getServiceImpl(ITopologyService.class);
-
- // read our config options
- Map<String, String> configOptions = context.getConfigParams(this);
- try {
- String idleTimeout = configOptions.get("idletimeout");
- if (idleTimeout != null) {
- FLOWMOD_DEFAULT_IDLE_TIMEOUT = Short.parseShort(idleTimeout);
- }
- } catch (NumberFormatException e) {
- log.warn("Error parsing flow idle timeout, " +
- "using default of {} seconds",
- FLOWMOD_DEFAULT_IDLE_TIMEOUT);
- }
- try {
- String hardTimeout = configOptions.get("hardtimeout");
- if (hardTimeout != null) {
- FLOWMOD_DEFAULT_HARD_TIMEOUT = Short.parseShort(hardTimeout);
- }
- } catch (NumberFormatException e) {
- log.warn("Error parsing flow hard timeout, " +
- "using default of {} seconds",
- FLOWMOD_DEFAULT_HARD_TIMEOUT);
- }
- log.debug("FlowMod idle timeout set to {} seconds",
- FLOWMOD_DEFAULT_IDLE_TIMEOUT);
- log.debug("FlowMod hard timeout set to {} seconds",
- FLOWMOD_DEFAULT_HARD_TIMEOUT);
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- super.startUp();
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/routing/BroadcastTree.java b/src/main/java/net/floodlightcontroller/routing/BroadcastTree.java
deleted file mode 100644
index 0c3703c..0000000
--- a/src/main/java/net/floodlightcontroller/routing/BroadcastTree.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.routing;
-import java.util.HashMap;
-
-import net.floodlightcontroller.routing.Link;
-
-import org.openflow.util.HexString;
-
-public class BroadcastTree {
- protected HashMap<Long, Link> links;
- protected HashMap<Long, Integer> costs;
-
- public BroadcastTree() {
- links = new HashMap<Long, Link>();
- costs = new HashMap<Long, Integer>();
- }
-
- public BroadcastTree(HashMap<Long, Link> links, HashMap<Long, Integer> costs) {
- this.links = links;
- this.costs = costs;
- }
-
- public Link getTreeLink(long node) {
- return links.get(node);
- }
-
- public int getCost(long node) {
- if (costs.get(node) == null) return -1;
- return (costs.get(node));
- }
-
- public HashMap<Long, Link> getLinks() {
- return links;
- }
-
- public void addTreeLink(long myNode, Link link) {
- links.put(myNode, link);
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- for(long n: links.keySet()) {
- sb.append("[" + HexString.toHexString(n) + ": cost=" + costs.get(n) + ", " + links.get(n) + "]");
- }
- return sb.toString();
- }
-
- public HashMap<Long, Integer> getCosts() {
- return costs;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
deleted file mode 100644
index c71ff87..0000000
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ /dev/null
@@ -1,683 +0,0 @@
-/**
- * Copyright 2011, Big Switch Networks, Inc.
- * Originally created by David Erickson, Stanford 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- **/
-
-package net.floodlightcontroller.routing;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.annotations.LogMessageDocs;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceListener;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.topology.NodePortTuple;
-import net.floodlightcontroller.util.OFMessageDamper;
-import net.floodlightcontroller.util.TimedCache;
-
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Abstract base class for implementing a forwarding module. Forwarding is
- * responsible for programming flows to a switch in response to a policy
- * decision.
- */
-@LogMessageCategory("Flow Programming")
-public abstract class ForwardingBase
- implements IOFMessageListener, IDeviceListener {
-
- protected final static Logger log =
- LoggerFactory.getLogger(ForwardingBase.class);
-
- protected static int OFMESSAGE_DAMPER_CAPACITY = 50000; // TODO: find sweet spot
- protected static int OFMESSAGE_DAMPER_TIMEOUT = 250; // ms
-
- public static short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 5; // in seconds
- public static short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0; // infinite
-
- protected IFloodlightProviderService floodlightProvider;
- protected IDeviceService deviceManager;
- protected IRoutingService routingEngine;
- protected ITopologyService topology;
-
- protected OFMessageDamper messageDamper;
-
- // for broadcast loop suppression
- protected boolean broadcastCacheFeature = true;
- public final int prime1 = 2633; // for hash calculation
- public final static int prime2 = 4357; // for hash calculation
- public TimedCache<Long> broadcastCache =
- new TimedCache<Long>(100, 5*1000); // 5 seconds interval;
-
- // flow-mod - for use in the cookie
- public static final int FORWARDING_APP_ID = 2; // TODO: This must be managed
- // by a global APP_ID class
- public long appCookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);
-
- // Comparator for sorting by SwitchCluster
- public Comparator<SwitchPort> clusterIdComparator =
- new Comparator<SwitchPort>() {
- @Override
- public int compare(SwitchPort d1, SwitchPort d2) {
- Long d1ClusterId =
- topology.getL2DomainId(d1.getSwitchDPID());
- Long d2ClusterId =
- topology.getL2DomainId(d2.getSwitchDPID());
- return d1ClusterId.compareTo(d2ClusterId);
- }
- };
-
- /**
- * init data structures
- *
- */
- protected void init() {
- messageDamper = new OFMessageDamper(OFMESSAGE_DAMPER_CAPACITY,
- EnumSet.of(OFType.FLOW_MOD),
- OFMESSAGE_DAMPER_TIMEOUT);
- }
-
- /**
- * Adds a listener for devicemanager and registers for PacketIns.
- */
- protected void startUp() {
- deviceManager.addListener(this);
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- }
-
- /**
- * Returns the application name "forwarding".
- */
- @Override
- public String getName() {
- return "forwarding";
- }
-
- /**
- * All subclasses must define this function if they want any specific
- * forwarding action
- *
- * @param sw
- * Switch that the packet came in from
- * @param pi
- * The packet that came in
- * @param decision
- * Any decision made by a policy engine
- */
- public abstract Command
- processPacketInMessage(IOFSwitch sw, OFPacketIn pi,
- IRoutingDecision decision,
- FloodlightContext cntx);
-
- @Override
- public Command receive(IOFSwitch sw, OFMessage msg,
- FloodlightContext cntx) {
- switch (msg.getType()) {
- case PACKET_IN:
- IRoutingDecision decision = null;
- if (cntx != null)
- decision =
- IRoutingDecision.rtStore.get(cntx,
- IRoutingDecision.CONTEXT_DECISION);
-
- return this.processPacketInMessage(sw,
- (OFPacketIn) msg,
- decision,
- cntx);
- default:
- break;
- }
- return Command.CONTINUE;
- }
-
- /**
- * Push routes from back to front
- * @param route Route to push
- * @param match OpenFlow fields to match on
- * @param srcSwPort Source switch port for the first hop
- * @param dstSwPort Destination switch port for final hop
- * @param cookie The cookie to set in each flow_mod
- * @param cntx The floodlight context
- * @param reqeustFlowRemovedNotifn if set to true then the switch would
- * send a flow mod removal notification when the flow mod expires
- * @param doFlush if set to true then the flow mod would be immediately
- * written to the switch
- * @param flowModCommand flow mod. command to use, e.g. OFFlowMod.OFPFC_ADD,
- * OFFlowMod.OFPFC_MODIFY etc.
- * @return srcSwitchIincluded True if the source switch is included in this route
- */
- @LogMessageDocs({
- @LogMessageDoc(level="WARN",
- message="Unable to push route, switch at DPID {dpid} not available",
- explanation="A switch along the calculated path for the " +
- "flow has disconnected.",
- recommendation=LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level="ERROR",
- message="Failure writing flow mod",
- explanation="An I/O error occurred while writing a " +
- "flow modification to a switch",
- recommendation=LogMessageDoc.CHECK_SWITCH)
- })
- public boolean pushRoute(Route route, OFMatch match,
- Integer wildcard_hints,
- OFPacketIn pi,
- long pinSwitch,
- long cookie,
- FloodlightContext cntx,
- boolean reqeustFlowRemovedNotifn,
- boolean doFlush,
- short flowModCommand) {
-
- boolean srcSwitchIncluded = false;
- OFFlowMod fm =
- (OFFlowMod) floodlightProvider.getOFMessageFactory()
- .getMessage(OFType.FLOW_MOD);
- OFActionOutput action = new OFActionOutput();
- action.setMaxLength((short)0xffff);
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(action);
-
- fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
- .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setCookie(cookie)
- .setCommand(flowModCommand)
- .setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-
- List<NodePortTuple> switchPortList = route.getPath();
-
- for (int indx = switchPortList.size()-1; indx > 0; indx -= 2) {
- // indx and indx-1 will always have the same switch DPID.
- long switchDPID = switchPortList.get(indx).getNodeId();
- IOFSwitch sw = floodlightProvider.getSwitches().get(switchDPID);
- if (sw == null) {
- if (log.isWarnEnabled()) {
- log.warn("Unable to push route, switch at DPID {} " +
- "not available", switchDPID);
- }
- return srcSwitchIncluded;
- }
-
- // set the match.
- fm.setMatch(wildcard(match, sw, wildcard_hints));
-
- // set buffer id if it is the source switch
- if (1 == indx) {
- // Set the flag to request flow-mod removal notifications only for the
- // source switch. The removal message is used to maintain the flow
- // cache. Don't set the flag for ARP messages - TODO generalize check
- if ((reqeustFlowRemovedNotifn)
- && (match.getDataLayerType() != Ethernet.TYPE_ARP)) {
- fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
- match.setWildcards(fm.getMatch().getWildcards());
- }
- }
-
- short outPort = switchPortList.get(indx).getPortId();
- short inPort = switchPortList.get(indx-1).getPortId();
- // set input and output ports on the switch
- fm.getMatch().setInputPort(inPort);
- ((OFActionOutput)fm.getActions().get(0)).setPort(outPort);
-
- try {
- if (log.isTraceEnabled()) {
- log.trace("Pushing Route flowmod routeIndx={} " +
- "sw={} inPort={} outPort={}",
- new Object[] {indx,
- sw,
- fm.getMatch().getInputPort(),
- outPort });
- }
- messageDamper.write(sw, fm, cntx);
- if (doFlush) {
- sw.flush();
- }
-
- // Push the packet out the source switch
- if (sw.getId() == pinSwitch) {
- // TODO: Instead of doing a packetOut here we could also
- // send a flowMod with bufferId set....
- pushPacket(sw, match, pi, outPort, cntx);
- srcSwitchIncluded = true;
- }
- } catch (IOException e) {
- log.error("Failure writing flow mod", e);
- }
-
- try {
- fm = fm.clone();
- } catch (CloneNotSupportedException e) {
- log.error("Failure cloning flow mod", e);
- }
- }
-
- return srcSwitchIncluded;
- }
-
- protected OFMatch wildcard(OFMatch match, IOFSwitch sw,
- Integer wildcard_hints) {
- if (wildcard_hints != null) {
- return match.clone().setWildcards(wildcard_hints.intValue());
- }
- return match.clone();
- }
-
- /**
- * Pushes a packet-out to a switch. If bufferId != BUFFER_ID_NONE we
- * assume that the packetOut switch is the same as the packetIn switch
- * and we will use the bufferId
- * Caller needs to make sure that inPort and outPort differs
- * @param packet packet data to send
- * @param sw switch from which packet-out is sent
- * @param bufferId bufferId
- * @param inPort input port
- * @param outPort output port
- * @param cntx context of the packet
- * @param flush force to flush the packet.
- */
- @LogMessageDocs({
- @LogMessageDoc(level="ERROR",
- message="BufferId is not and packet data is null. " +
- "Cannot send packetOut. " +
- "srcSwitch={dpid} inPort={port} outPort={port}",
- explanation="The switch send a malformed packet-in." +
- "The packet will be dropped",
- recommendation=LogMessageDoc.REPORT_SWITCH_BUG),
- @LogMessageDoc(level="ERROR",
- message="Failure writing packet out",
- explanation="An I/O error occurred while writing a " +
- "packet out to a switch",
- recommendation=LogMessageDoc.CHECK_SWITCH)
- })
- public void pushPacket(IPacket packet,
- IOFSwitch sw,
- int bufferId,
- short inPort,
- short outPort,
- FloodlightContext cntx,
- boolean flush) {
-
-
- if (log.isTraceEnabled()) {
- log.trace("PacketOut srcSwitch={} inPort={} outPort={}",
- new Object[] {sw, inPort, outPort});
- }
-
- OFPacketOut po =
- (OFPacketOut) floodlightProvider.getOFMessageFactory()
- .getMessage(OFType.PACKET_OUT);
-
- // set actions
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(new OFActionOutput(outPort, (short) 0xffff));
-
- po.setActions(actions)
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
- short poLength =
- (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
-
- // set buffer_id, in_port
- po.setBufferId(bufferId);
- po.setInPort(inPort);
-
- // set data - only if buffer_id == -1
- if (po.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
- if (packet == null) {
- log.error("BufferId is not set and packet data is null. " +
- "Cannot send packetOut. " +
- "srcSwitch={} inPort={} outPort={}",
- new Object[] {sw, inPort, outPort});
- return;
- }
- byte[] packetData = packet.serialize();
- poLength += packetData.length;
- po.setPacketData(packetData);
- }
-
- po.setLength(poLength);
-
- try {
- messageDamper.write(sw, po, cntx, flush);
- } catch (IOException e) {
- log.error("Failure writing packet out", e);
- }
- }
-
- /**
- * Pushes a packet-out to a switch. The assumption here is that
- * the packet-in was also generated from the same switch. Thus, if the input
- * port of the packet-in and the outport are the same, the function will not
- * push the packet-out.
- * @param sw switch that generated the packet-in, and from which packet-out is sent
- * @param match OFmatch
- * @param pi packet-in
- * @param outport output port
- * @param cntx context of the packet
- */
- protected void pushPacket(IOFSwitch sw, OFMatch match, OFPacketIn pi,
- short outport, FloodlightContext cntx) {
-
- if (pi == null) {
- return;
- } else if (pi.getInPort() == outport){
- log.warn("Packet out not sent as the outport matches inport. {}",
- pi);
- return;
- }
-
- // The assumption here is (sw) is the switch that generated the
- // packet-in. If the input port is the same as output port, then
- // the packet-out should be ignored.
- if (pi.getInPort() == outport) {
- if (log.isDebugEnabled()) {
- log.debug("Attempting to do packet-out to the same " +
- "interface as packet-in. Dropping packet. " +
- " SrcSwitch={}, match = {}, pi={}",
- new Object[]{sw, match, pi});
- return;
- }
- }
-
- if (log.isTraceEnabled()) {
- log.trace("PacketOut srcSwitch={} match={} pi={}",
- new Object[] {sw, match, pi});
- }
-
- OFPacketOut po =
- (OFPacketOut) floodlightProvider.getOFMessageFactory()
- .getMessage(OFType.PACKET_OUT);
-
- // set actions
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(new OFActionOutput(outport, (short) 0xffff));
-
- po.setActions(actions)
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
- short poLength =
- (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
-
- // If the switch doens't support buffering set the buffer id to be none
- // otherwise it'll be the the buffer id of the PacketIn
- if (sw.getBuffers() == 0) {
- // We set the PI buffer id here so we don't have to check again below
- pi.setBufferId(OFPacketOut.BUFFER_ID_NONE);
- po.setBufferId(OFPacketOut.BUFFER_ID_NONE);
- } else {
- po.setBufferId(pi.getBufferId());
- }
-
- po.setInPort(pi.getInPort());
-
- // If the buffer id is none or the switch doesn's support buffering
- // we send the data with the packet out
- if (pi.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
- byte[] packetData = pi.getPacketData();
- poLength += packetData.length;
- po.setPacketData(packetData);
- }
-
- po.setLength(poLength);
-
- try {
- messageDamper.write(sw, po, cntx);
- } catch (IOException e) {
- log.error("Failure writing packet out", e);
- }
- }
-
-
- /**
- * Write packetout message to sw with output actions to one or more
- * output ports with inPort/outPorts passed in.
- * @param packetData
- * @param sw
- * @param inPort
- * @param ports
- * @param cntx
- */
- public void packetOutMultiPort(byte[] packetData,
- IOFSwitch sw,
- short inPort,
- Set<Integer> outPorts,
- FloodlightContext cntx) {
- //setting actions
- List<OFAction> actions = new ArrayList<OFAction>();
-
- Iterator<Integer> j = outPorts.iterator();
-
- while (j.hasNext())
- {
- actions.add(new OFActionOutput(j.next().shortValue(),
- (short) 0));
- }
-
- OFPacketOut po =
- (OFPacketOut) floodlightProvider.getOFMessageFactory().
- getMessage(OFType.PACKET_OUT);
- po.setActions(actions);
- po.setActionsLength((short) (OFActionOutput.MINIMUM_LENGTH *
- outPorts.size()));
-
- // set buffer-id to BUFFER_ID_NONE, and set in-port to OFPP_NONE
- po.setBufferId(OFPacketOut.BUFFER_ID_NONE);
- po.setInPort(inPort);
-
- // data (note buffer_id is always BUFFER_ID_NONE) and length
- short poLength = (short)(po.getActionsLength() +
- OFPacketOut.MINIMUM_LENGTH);
- poLength += packetData.length;
- po.setPacketData(packetData);
- po.setLength(poLength);
-
- try {
- if (log.isTraceEnabled()) {
- log.trace("write broadcast packet on switch-id={} " +
- "interfaces={} packet-out={}",
- new Object[] {sw.getId(), outPorts, po});
- }
- messageDamper.write(sw, po, cntx);
-
- } catch (IOException e) {
- log.error("Failure writing packet out", e);
- }
- }
-
- /**
- * @see packetOutMultiPort
- * Accepts a PacketIn instead of raw packet data. Note that the inPort
- * and switch can be different than the packet in switch/port
- */
- public void packetOutMultiPort(OFPacketIn pi,
- IOFSwitch sw,
- short inPort,
- Set<Integer> outPorts,
- FloodlightContext cntx) {
- packetOutMultiPort(pi.getPacketData(), sw, inPort, outPorts, cntx);
- }
-
- /**
- * @see packetOutMultiPort
- * Accepts an IPacket instead of raw packet data. Note that the inPort
- * and switch can be different than the packet in switch/port
- */
- public void packetOutMultiPort(IPacket packet,
- IOFSwitch sw,
- short inPort,
- Set<Integer> outPorts,
- FloodlightContext cntx) {
- packetOutMultiPort(packet.serialize(), sw, inPort, outPorts, cntx);
- }
-
- protected boolean isInBroadcastCache(IOFSwitch sw, OFPacketIn pi,
- FloodlightContext cntx) {
- // Get the cluster id of the switch.
- // Get the hash of the Ethernet packet.
- if (sw == null) return true;
-
- // If the feature is disabled, always return false;
- if (!broadcastCacheFeature) return false;
-
- Ethernet eth =
- IFloodlightProviderService.bcStore.get(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
- Long broadcastHash;
- broadcastHash = topology.getL2DomainId(sw.getId()) * prime1 +
- pi.getInPort() * prime2 + eth.hashCode();
- if (broadcastCache.update(broadcastHash)) {
- sw.updateBroadcastCache(broadcastHash, pi.getInPort());
- return true;
- } else {
- return false;
- }
- }
-
- protected boolean isInSwitchBroadcastCache(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
- if (sw == null) return true;
-
- // If the feature is disabled, always return false;
- if (!broadcastCacheFeature) return false;
-
- // Get the hash of the Ethernet packet.
- Ethernet eth =
- IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
- long hash = pi.getInPort() * prime2 + eth.hashCode();
-
- // some FORWARD_OR_FLOOD packets are unicast with unknown destination mac
- return sw.updateBroadcastCache(hash, pi.getInPort());
- }
-
- @LogMessageDocs({
- @LogMessageDoc(level="ERROR",
- message="Failure writing deny flow mod",
- explanation="An I/O error occurred while writing a " +
- "deny flow mod to a switch",
- recommendation=LogMessageDoc.CHECK_SWITCH)
- })
- public static boolean
- blockHost(IFloodlightProviderService floodlightProvider,
- SwitchPort sw_tup, long host_mac,
- short hardTimeout, long cookie) {
-
- if (sw_tup == null) {
- return false;
- }
-
- IOFSwitch sw =
- floodlightProvider.getSwitches().get(sw_tup.getSwitchDPID());
- if (sw == null) return false;
- int inputPort = sw_tup.getPort();
- log.debug("blockHost sw={} port={} mac={}",
- new Object[] { sw, sw_tup.getPort(), new Long(host_mac) });
-
- // Create flow-mod based on packet-in and src-switch
- OFFlowMod fm =
- (OFFlowMod) floodlightProvider.getOFMessageFactory()
- .getMessage(OFType.FLOW_MOD);
- OFMatch match = new OFMatch();
- List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to
- // drop
- match.setDataLayerSource(Ethernet.toByteArray(host_mac))
- .setInputPort((short)inputPort)
- .setWildcards(OFMatch.OFPFW_ALL & ~OFMatch.OFPFW_DL_SRC
- & ~OFMatch.OFPFW_IN_PORT);
- fm.setCookie(cookie)
- .setHardTimeout((short) hardTimeout)
- .setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
- .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH);
-
- try {
- log.debug("write drop flow-mod sw={} match={} flow-mod={}",
- new Object[] { sw, match, fm });
- // TODO: can't use the message damper sine this method is static
- sw.write(fm, null);
- } catch (IOException e) {
- log.error("Failure writing deny flow mod", e);
- return false;
- }
- return true;
-
- }
-
- @Override
- public void deviceAdded(IDevice device) {
- // NOOP
- }
-
- @Override
- public void deviceRemoved(IDevice device) {
- // NOOP
- }
-
- @Override
- public void deviceMoved(IDevice device) {
- }
-
- @Override
- public void deviceIPV4AddrChanged(IDevice device) {
-
- }
-
- @Override
- public void deviceVlanChanged(IDevice device) {
-
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return (type.equals(OFType.PACKET_IN) &&
- (name.equals("topology") ||
- name.equals("devicemanager")));
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return false;
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java b/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java
deleted file mode 100644
index ed72706..0000000
--- a/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.routing;
-
-import java.util.List;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.FloodlightContextStore;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-
-public interface IRoutingDecision {
- public enum RoutingAction {
- /*
- * NONE: NO-OP, continue with the packet processing chain
- * DROP: Drop this packet and this flow
- * FORWARD: Forward this packet, and this flow, to the first (and only device) in getDestinationDevices(),
- * if the destination is not known at this time, initiate a discovery action for it (e.g. ARP)
- * FORWARD_OR_FLOOD: Forward this packet, and this flow, to the first (and only device) in getDestinationDevices(),
- * if the destination is not known at this time, flood this packet on the source switch
- * BROADCAST: Broadcast this packet on all links
- * MULTICAST: Multicast this packet to all the interfaces and devices attached
- */
- NONE, DROP, FORWARD, FORWARD_OR_FLOOD, BROADCAST, MULTICAST
- }
-
- public static final FloodlightContextStore<IRoutingDecision> rtStore =
- new FloodlightContextStore<IRoutingDecision>();
- public static final String CONTEXT_DECISION =
- "net.floodlightcontroller.routing.decision";
-
- public void addToContext(FloodlightContext cntx);
- public RoutingAction getRoutingAction();
- public void setRoutingAction(RoutingAction action);
- public SwitchPort getSourcePort();
- public IDevice getSourceDevice();
- public List<IDevice> getDestinationDevices();
- public void addDestinationDevice(IDevice d);
- public List<SwitchPort> getMulticastInterfaces();
- public void setMulticastInterfaces(List<SwitchPort> lspt);
- public Integer getWildcards();
- public void setWildcards(Integer wildcards);
-}
diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingService.java b/src/main/java/net/floodlightcontroller/routing/IRoutingService.java
deleted file mode 100644
index fcd70ad..0000000
--- a/src/main/java/net/floodlightcontroller/routing/IRoutingService.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.routing;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.routing.Route;
-
-public interface IRoutingService extends IFloodlightService {
-
- /** Provides a route between src and dst that allows tunnels. */
- public Route getRoute(long src, long dst);
-
- /** Provides a route between src and dst, with option to allow or
- * not allow tunnels in the path.*/
- public Route getRoute(long src, long dst, boolean tunnelEnabled);
-
-
- public Route getRoute(long srcId, short srcPort,
- long dstId, short dstPort);
-
- public Route getRoute(long srcId, short srcPort,
- long dstId, short dstPort,
- boolean tunnelEnabled);
-
- /** Check if a route exists between src and dst, including tunnel links
- * in the path.
- */
- public boolean routeExists(long src, long dst);
-
- /** Check if a route exists between src and dst, with option to have
- * or not have tunnels as part of the path.
- */
- public boolean routeExists(long src, long dst, boolean tunnelEnabled);
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/routing/Route.java b/src/main/java/net/floodlightcontroller/routing/Route.java
deleted file mode 100755
index 211a924..0000000
--- a/src/main/java/net/floodlightcontroller/routing/Route.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.routing;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.floodlightcontroller.topology.NodePortTuple;
-
-/**
- * Represents a route between two switches
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class Route implements Comparable<Route> {
- protected RouteId id;
- protected List<NodePortTuple> switchPorts;
-
- public Route(RouteId id, List<NodePortTuple> switchPorts) {
- super();
- this.id = id;
- this.switchPorts = switchPorts;
- }
-
- public Route(Long src, Long dst) {
- super();
- this.id = new RouteId(src, dst);
- this.switchPorts = new ArrayList<NodePortTuple>();
- }
-
- /**
- * @return the id
- */
- public RouteId getId() {
- return id;
- }
-
- /**
- * @param id the id to set
- */
- public void setId(RouteId id) {
- this.id = id;
- }
-
- /**
- * @return the path
- */
- public List<NodePortTuple> getPath() {
- return switchPorts;
- }
-
- /**
- * @param path the path to set
- */
- public void setPath(List<NodePortTuple> switchPorts) {
- this.switchPorts = switchPorts;
- }
-
- @Override
- public int hashCode() {
- final int prime = 5791;
- int result = 1;
- result = prime * result + ((id == null) ? 0 : id.hashCode());
- result = prime * result + ((switchPorts == null) ? 0 : switchPorts.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;
- Route other = (Route) obj;
- if (id == null) {
- if (other.id != null)
- return false;
- } else if (!id.equals(other.id))
- return false;
- if (switchPorts == null) {
- if (other.switchPorts != null)
- return false;
- } else if (!switchPorts.equals(other.switchPorts))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "Route [id=" + id + ", switchPorts=" + switchPorts + "]";
- }
-
- /**
- * Compares the path lengths between Routes.
- */
- @Override
- public int compareTo(Route o) {
- return ((Integer)switchPorts.size()).compareTo(o.switchPorts.size());
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/routing/RouteId.java b/src/main/java/net/floodlightcontroller/routing/RouteId.java
deleted file mode 100755
index a550961..0000000
--- a/src/main/java/net/floodlightcontroller/routing/RouteId.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.routing;
-
-import org.openflow.util.HexString;
-
-/**
- * Stores the endpoints of a route, in this case datapath ids
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class RouteId implements Cloneable, Comparable<RouteId> {
- protected Long src;
- protected Long dst;
-
- public RouteId(Long src, Long dst) {
- super();
- this.src = src;
- this.dst = dst;
- }
-
- public Long getSrc() {
- return src;
- }
-
- public void setSrc(Long src) {
- this.src = src;
- }
-
- public Long getDst() {
- return dst;
- }
-
- public void setDst(Long dst) {
- this.dst = dst;
- }
-
- @Override
- public int hashCode() {
- final int prime = 2417;
- int result = 1;
- result = prime * result + ((dst == null) ? 0 : dst.hashCode());
- result = prime * result + ((src == null) ? 0 : src.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;
- RouteId other = (RouteId) obj;
- if (dst == null) {
- if (other.dst != null)
- return false;
- } else if (!dst.equals(other.dst))
- return false;
- if (src == null) {
- if (other.src != null)
- return false;
- } else if (!src.equals(other.src))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "RouteId [src=" + HexString.toHexString(this.src) + " dst="
- + HexString.toHexString(this.dst) + "]";
- }
-
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
- @Override
- public int compareTo(RouteId o) {
- int result = src.compareTo(o.getSrc());
- if (result != 0)
- return result;
- return dst.compareTo(o.getDst());
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/routing/RoutingDecision.java b/src/main/java/net/floodlightcontroller/routing/RoutingDecision.java
deleted file mode 100644
index 5b32b23..0000000
--- a/src/main/java/net/floodlightcontroller/routing/RoutingDecision.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package net.floodlightcontroller.routing;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-
-
-public class RoutingDecision implements IRoutingDecision {
-
- protected RoutingAction action;
- protected Integer wildcards;
- protected SwitchPort srcPort;
- protected IDevice srcDevice;
- protected List<IDevice> destDevices;
- protected List<SwitchPort> broadcastIntertfaces;
-
- public RoutingDecision(long swDipd,
- short inPort,
- IDevice srcDevice,
- RoutingAction action) {
- this.srcPort = new SwitchPort(swDipd, inPort);
- this.srcDevice = srcDevice;
- this.destDevices =
- Collections.synchronizedList(new ArrayList<IDevice>());
- this.broadcastIntertfaces =
- Collections.synchronizedList(new ArrayList<SwitchPort>());
- this.action = action;
- this.wildcards = null;
- }
-
- @Override
- public RoutingAction getRoutingAction() {
- return this.action;
- }
-
- @Override
- public void setRoutingAction(RoutingAction action) {
- this.action = action;
- }
-
- @Override
- public SwitchPort getSourcePort() {
- return this.srcPort;
- }
-
- @Override
- public IDevice getSourceDevice() {
- return this.srcDevice;
- }
-
- @Override
- public List<IDevice> getDestinationDevices() {
- return this.destDevices;
- }
-
- @Override
- public void addDestinationDevice(IDevice d) {
- if (!destDevices.contains(d)) {
- destDevices.add(d);
- }
- }
-
- @Override
- public void setMulticastInterfaces(List<SwitchPort> lspt) {
- this.broadcastIntertfaces = lspt;
- }
-
- @Override
- public List<SwitchPort> getMulticastInterfaces() {
- return this.broadcastIntertfaces;
- }
-
- @Override
- public Integer getWildcards() {
- return this.wildcards;
- }
-
- @Override
- public void setWildcards(Integer wildcards) {
- this.wildcards = wildcards;
- }
-
- @Override
- public void addToContext(FloodlightContext cntx) {
- rtStore.put(cntx, IRoutingDecision.CONTEXT_DECISION, this);
- }
-
- public String toString() {
- return "action " + action +
- " wildcard " +
- ((wildcards == null) ? null : "0x"+Integer.toHexString(wildcards.intValue()));
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/Cluster.java b/src/main/java/net/floodlightcontroller/topology/Cluster.java
deleted file mode 100644
index 606b079..0000000
--- a/src/main/java/net/floodlightcontroller/topology/Cluster.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package net.floodlightcontroller.topology;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import net.floodlightcontroller.routing.Link;
-
-import org.openflow.util.HexString;
-
-public class Cluster {
- protected long id; // the lowest id of the nodes
- protected Map<Long, Set<Link>> links; // set of links connected to a node.
-
- public Cluster() {
- id = Long.MAX_VALUE;
- links = new HashMap<Long, Set<Link>>();
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- public Map<Long, Set<Link>> getLinks() {
- return links;
- }
-
- public Set<Long> getNodes() {
- return links.keySet();
- }
-
- void add(long n) {
- if (links.containsKey(n) == false) {
- links.put(n, new HashSet<Link>());
- if (n < id) id = n;
- }
- }
-
- void addLink(Link l) {
- if (links.containsKey(l.getSrc()) == false) {
- links.put(l.getSrc(), new HashSet<Link>());
- if (l.getSrc() < id) id = l.getSrc();
- }
- links.get(l.getSrc()).add(l);
-
- if (links.containsKey(l.getDst()) == false) {
- links.put(l.getDst(), new HashSet<Link>());
- if (l.getDst() < id) id = l.getDst();
- }
- links.get(l.getDst()).add(l);
- }
-
- @Override
- public int hashCode() {
- return (int) (id + id >>>32);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
-
- Cluster other = (Cluster) obj;
- return (this.id == other.id);
- }
-
- public String toString() {
- return "[Cluster id=" + HexString.toHexString(id) + ", " + links.keySet() + "]";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/ITopologyListener.java b/src/main/java/net/floodlightcontroller/topology/ITopologyListener.java
deleted file mode 100644
index 9f06992..0000000
--- a/src/main/java/net/floodlightcontroller/topology/ITopologyListener.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.floodlightcontroller.topology;
-
-public interface ITopologyListener {
- /**
- * Happens when the switch clusters are recomputed
- */
- void topologyChanged();
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
deleted file mode 100644
index 31032c9..0000000
--- a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package net.floodlightcontroller.topology;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
-
-public interface ITopologyService extends IFloodlightService {
-
- public void addListener(ITopologyListener listener);
-
- public Date getLastUpdateTime();
-
- /**
- * Query to determine if devices must be learned on a given switch port.
- */
- public boolean isAttachmentPointPort(long switchid, short port);
- public boolean isAttachmentPointPort(long switchid, short port,
- boolean tunnelEnabled);
-
- public long getOpenflowDomainId(long switchId);
- public long getOpenflowDomainId(long switchId, boolean tunnelEnabled);
-
- /**
- * Returns the identifier of the L2 domain of a given switch.
- * @param switchId The DPID of the switch in long form
- * @return The DPID of the switch that is the key for the cluster
- */
- public long getL2DomainId(long switchId);
- public long getL2DomainId(long switchId, boolean tunnelEnabled);
-
- /**
- * Queries whether two switches are in the same cluster.
- * @param switch1
- * @param switch2
- * @return true if the switches are in the same cluster
- */
- public boolean inSameOpenflowDomain(long switch1, long switch2);
- public boolean inSameOpenflowDomain(long switch1, long switch2,
- boolean tunnelEnabled);
-
- /**
- * Queries whether two switches are in the same island.
- * Currently, island and cluster are the same. In future,
- * islands could be different than clusters.
- * @param switch1
- * @param switch2
- * @return True of they are in the same island, false otherwise
- */
- public boolean inSameL2Domain(long switch1, long switch2);
- public boolean inSameL2Domain(long switch1, long switch2,
- boolean tunnelEnabled);
-
- public boolean isBroadcastDomainPort(long sw, short port);
- public boolean isBroadcastDomainPort(long sw, short port,
- boolean tunnelEnabled);
-
-
- public boolean isAllowed(long sw, short portId);
- public boolean isAllowed(long sw, short portId, boolean tunnelEnabled);
-
- /**
- * Indicates if an attachment point on the new switch port is consistent
- * with the attachment point on the old switch port or not.
- */
- public boolean isConsistent(long oldSw, short oldPort,
- long newSw, short newPort);
- public boolean isConsistent(long oldSw, short oldPort,
- long newSw, short newPort,
- boolean tunnelEnabled);
-
- /**
- * Indicates if the two switch ports are connected to the same
- * broadcast domain or not.
- * @param s1
- * @param p1
- * @param s2
- * @param p2
- * @return
- */
- public boolean isInSameBroadcastDomain(long s1, short p1,
- long s2, short p2);
- public boolean isInSameBroadcastDomain(long s1, short p1,
- long s2, short p2,
- boolean tunnelEnabled);
-
- /**
- * Gets a list of ports on a given switch that are known to topology.
- * @param sw The switch DPID in long
- * @return The set of ports on this switch
- */
- public Set<Short> getPortsWithLinks(long sw);
- public Set<Short> getPortsWithLinks(long sw, boolean tunnelEnabled);
-
- /** Get broadcast ports on a target switch for a given attachmentpoint
- * point port.
- */
- public Set<Short> getBroadcastPorts(long targetSw, long src, short srcPort);
-
- public Set<Short> getBroadcastPorts(long targetSw, long src, short srcPort,
- boolean tunnelEnabled);
-
- /**
- *
- */
- public boolean isIncomingBroadcastAllowed(long sw, short portId);
- public boolean isIncomingBroadcastAllowed(long sw, short portId,
- boolean tunnelEnabled);
-
-
- /** Get the proper outgoing switchport for a given pair of src-dst
- * switchports.
- */
- public NodePortTuple getOutgoingSwitchPort(long src, short srcPort,
- long dst, short dstPort);
-
-
- public NodePortTuple getOutgoingSwitchPort(long src, short srcPort,
- long dst, short dstPort,
- boolean tunnelEnabled);
-
-
- public NodePortTuple getIncomingSwitchPort(long src, short srcPort,
- long dst, short dstPort);
- public NodePortTuple getIncomingSwitchPort(long src, short srcPort,
- long dst, short dstPort,
- boolean tunnelEnabled);
-
- /**
- * If the dst is not allowed by the higher-level topology,
- * this method provides the topologically equivalent broadcast port.
- * @param src
- * @param dst
- * @return the allowed broadcast port
- */
- public NodePortTuple
- getAllowedOutgoingBroadcastPort(long src,
- short srcPort,
- long dst,
- short dstPort);
-
- public NodePortTuple
- getAllowedOutgoingBroadcastPort(long src,
- short srcPort,
- long dst,
- short dstPort,
- boolean tunnelEnabled);
-
- /**
- * If the src broadcast domain port is not allowed for incoming
- * broadcast, this method provides the topologically equivalent
- * incoming broadcast-allowed
- * src port.
- * @param src
- * @param dst
- * @return the allowed broadcast port
- */
- public NodePortTuple
- getAllowedIncomingBroadcastPort(long src,
- short srcPort);
-
- public NodePortTuple
- getAllowedIncomingBroadcastPort(long src,
- short srcPort,
- boolean tunnelEnabled);
-
-
- /**
- * Gets the set of ports that belong to a broadcast domain.
- * @return The set of ports that belong to a broadcast domain.
- */
- public Set<NodePortTuple> getBroadcastDomainPorts();
- public Set<NodePortTuple> getTunnelPorts();
-
-
- /**
- * Returns a set of blocked ports. The set of blocked
- * ports is the union of all the blocked ports across all
- * instances.
- * @return
- */
- public Set<NodePortTuple> getBlockedPorts();
-
- /**
- * ITopologyListener provides topologyChanged notification,
- * but not *what* the changes were.
- * This method returns the delta in the linkUpdates between the current and the previous topology instance.
- * @return
- */
- public List<LDUpdate> getLastLinkUpdates();
-
- /**
- * Switch methods
- */
- public Set<Short> getPorts(long sw);
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/NodePair.java b/src/main/java/net/floodlightcontroller/topology/NodePair.java
deleted file mode 100644
index ff954a0..0000000
--- a/src/main/java/net/floodlightcontroller/topology/NodePair.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package net.floodlightcontroller.topology;
-
-public class NodePair {
- private long min;
- private long max;
-
- public NodePair(long a, long b) {
- if (a < b) {
- min = a;
- max = b;
- } else {
- min = b;
- max = a;
- }
- }
-
- public long getNode() {
- return min;
- }
-
- public long getOtherNode() {
- return max;
- }
-
- public String toString() {
- return "[" + new Long(min) + ", " + new Long(max) + "]";
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + (int) (max ^ (max >>> 32));
- result = prime * result + (int) (min ^ (min >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- NodePair other = (NodePair) obj;
- if (max != other.max)
- return false;
- if (min != other.min)
- return false;
- return true;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/OrderedNodePair.java b/src/main/java/net/floodlightcontroller/topology/OrderedNodePair.java
deleted file mode 100644
index af9e677..0000000
--- a/src/main/java/net/floodlightcontroller/topology/OrderedNodePair.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package net.floodlightcontroller.topology;
-
-public class OrderedNodePair {
- private long src;
- private long dst;
-
- public OrderedNodePair(long s, long d) {
- src = s;
- dst = d;
- }
-
- public long getSrc() {
- return src;
- }
-
- public long getDst() {
- return dst;
- }
-
- @Override
- public int hashCode() {
- final int prime = 2417;
- int result = 1;
- result = prime * result + (int) (dst ^ (dst >>> 32));
- result = prime * result + (int) (src ^ (src >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- OrderedNodePair other = (OrderedNodePair) obj;
- if (dst != other.dst)
- return false;
- if (src != other.src)
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "OrderedNodePair [src=" + src + ", dst=" + dst + "]";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
deleted file mode 100644
index bda36a6..0000000
--- a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
+++ /dev/null
@@ -1,782 +0,0 @@
-package net.floodlightcontroller.topology;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.PriorityQueue;
-import java.util.Set;
-
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.util.ClusterDFS;
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.routing.BroadcastTree;
-import net.floodlightcontroller.routing.Link;
-import net.floodlightcontroller.routing.Route;
-import net.floodlightcontroller.routing.RouteId;
-import net.floodlightcontroller.util.LRUHashMap;
-
-/**
- * A representation of a network topology. Used internally by
- * {@link TopologyManager}
- */
-@LogMessageCategory("Network Topology")
-public class TopologyInstance {
-
- public static final short LT_SH_LINK = 1;
- public static final short LT_BD_LINK = 2;
- public static final short LT_TUNNEL = 3;
-
- public static final int MAX_LINK_WEIGHT = 10000;
- public static final int MAX_PATH_WEIGHT = Integer.MAX_VALUE - MAX_LINK_WEIGHT - 1;
- public static final int PATH_CACHE_SIZE = 1000;
-
- protected final static Logger log = LoggerFactory.getLogger(TopologyInstance.class);
-
- protected Map<Long, Set<Short>> switchPorts; // Set of ports for each switch
- /** Set of switch ports that are marked as blocked. A set of blocked
- * switch ports may be provided at the time of instantiation. In addition,
- * we may add additional ports to this set.
- */
- protected Set<NodePortTuple> blockedPorts;
- protected Map<NodePortTuple, Set<Link>> switchPortLinks; // Set of links organized by node port tuple
- /** Set of links that are blocked. */
- protected Set<Link> blockedLinks;
-
- protected Set<Long> switches;
- protected Set<NodePortTuple> broadcastDomainPorts;
- protected Set<NodePortTuple> tunnelPorts;
-
- protected Set<Cluster> clusters; // set of openflow domains
- protected Map<Long, Cluster> switchClusterMap; // switch to OF domain map
-
- // States for routing
- protected Map<Long, BroadcastTree> destinationRootedTrees;
- protected Map<Long, Set<NodePortTuple>> clusterBroadcastNodePorts;
- protected Map<Long, BroadcastTree> clusterBroadcastTrees;
- protected LRUHashMap<RouteId, Route> pathcache;
-
- public TopologyInstance() {
- this.switches = new HashSet<Long>();
- this.switchPorts = new HashMap<Long, Set<Short>>();
- this.switchPortLinks = new HashMap<NodePortTuple, Set<Link>>();
- this.broadcastDomainPorts = new HashSet<NodePortTuple>();
- this.tunnelPorts = new HashSet<NodePortTuple>();
- this.blockedPorts = new HashSet<NodePortTuple>();
- this.blockedLinks = new HashSet<Link>();
- }
-
- public TopologyInstance(Map<Long, Set<Short>> switchPorts,
- Map<NodePortTuple, Set<Link>> switchPortLinks)
- {
- this.switches = new HashSet<Long>(switchPorts.keySet());
- this.switchPorts = new HashMap<Long, Set<Short>>(switchPorts);
- this.switchPortLinks = new HashMap<NodePortTuple,
- Set<Link>>(switchPortLinks);
- this.broadcastDomainPorts = new HashSet<NodePortTuple>();
- this.tunnelPorts = new HashSet<NodePortTuple>();
- this.blockedPorts = new HashSet<NodePortTuple>();
- this.blockedLinks = new HashSet<Link>();
-
- clusters = new HashSet<Cluster>();
- switchClusterMap = new HashMap<Long, Cluster>();
- }
- public TopologyInstance(Map<Long, Set<Short>> switchPorts,
- Set<NodePortTuple> blockedPorts,
- Map<NodePortTuple, Set<Link>> switchPortLinks,
- Set<NodePortTuple> broadcastDomainPorts,
- Set<NodePortTuple> tunnelPorts){
-
- // copy these structures
- this.switches = new HashSet<Long>(switchPorts.keySet());
- this.switchPorts = new HashMap<Long, Set<Short>>();
- for(long sw: switchPorts.keySet()) {
- this.switchPorts.put(sw, new HashSet<Short>(switchPorts.get(sw)));
- }
-
- this.blockedPorts = new HashSet<NodePortTuple>(blockedPorts);
- this.switchPortLinks = new HashMap<NodePortTuple, Set<Link>>();
- for(NodePortTuple npt: switchPortLinks.keySet()) {
- this.switchPortLinks.put(npt,
- new HashSet<Link>(switchPortLinks.get(npt)));
- }
- this.broadcastDomainPorts = new HashSet<NodePortTuple>(broadcastDomainPorts);
- this.tunnelPorts = new HashSet<NodePortTuple>(tunnelPorts);
-
- blockedLinks = new HashSet<Link>();
- clusters = new HashSet<Cluster>();
- switchClusterMap = new HashMap<Long, Cluster>();
- destinationRootedTrees = new HashMap<Long, BroadcastTree>();
- clusterBroadcastTrees = new HashMap<Long, BroadcastTree>();
- clusterBroadcastNodePorts = new HashMap<Long, Set<NodePortTuple>>();
- pathcache = new LRUHashMap<RouteId, Route>(PATH_CACHE_SIZE);
- }
-
- public void compute() {
-
- // Step 1: Compute clusters ignoring broadcast domain links
- // Create nodes for clusters in the higher level topology
- // Must ignore blocked links.
- identifyOpenflowDomains();
-
- // Step 0: Remove all links connected to blocked ports.
- // removeLinksOnBlockedPorts();
-
-
- // Step 1.1: Add links to clusters
- // Avoid adding blocked links to clusters
- addLinksToOpenflowDomains();
-
- // Step 2. Compute shortest path trees in each cluster for
- // unicast routing. The trees are rooted at the destination.
- // Cost for tunnel links and direct links are the same.
- calculateShortestPathTreeInClusters();
-
- // Step 3. Compute broadcast tree in each cluster.
- // Cost for tunnel links are high to discourage use of
- // tunnel links. The cost is set to the number of nodes
- // in the cluster + 1, to use as minimum number of
- // clusters as possible.
- calculateBroadcastNodePortsInClusters();
-
- // Step 4. print topology.
- // printTopology();
- }
-
- public void printTopology() {
- log.trace("-----------------------------------------------");
- log.trace("Links: {}",this.switchPortLinks);
- log.trace("broadcastDomainPorts: {}", broadcastDomainPorts);
- log.trace("tunnelPorts: {}", tunnelPorts);
- log.trace("clusters: {}", clusters);
- log.trace("destinationRootedTrees: {}", destinationRootedTrees);
- log.trace("clusterBroadcastNodePorts: {}", clusterBroadcastNodePorts);
- log.trace("-----------------------------------------------");
- }
-
- protected void addLinksToOpenflowDomains() {
- for(long s: switches) {
- if (switchPorts.get(s) == null) continue;
- for (short p: switchPorts.get(s)) {
- NodePortTuple np = new NodePortTuple(s, p);
- if (switchPortLinks.get(np) == null) continue;
- if (isBroadcastDomainPort(np)) continue;
- for(Link l: switchPortLinks.get(np)) {
- if (isBlockedLink(l)) continue;
- if (isBroadcastDomainLink(l)) continue;
- Cluster c1 = switchClusterMap.get(l.getSrc());
- Cluster c2 = switchClusterMap.get(l.getDst());
- if (c1 ==c2) {
- c1.addLink(l);
- }
- }
- }
- }
- }
-
- /**
- * @author Srinivasan Ramasubramanian
- *
- * This function divides the network into clusters. Every cluster is
- * a strongly connected component. The network may contain unidirectional
- * links. The function calls dfsTraverse for performing depth first
- * search and cluster formation.
- *
- * The computation of strongly connected components is based on
- * Tarjan's algorithm. For more details, please see the Wikipedia
- * link below.
- *
- * http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
- */
- @LogMessageDoc(level="ERROR",
- message="No DFS object for switch {} found.",
- explanation="The internal state of the topology module is corrupt",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
- public void identifyOpenflowDomains() {
- Map<Long, ClusterDFS> dfsList = new HashMap<Long, ClusterDFS>();
-
- if (switches == null) return;
-
- for (Long key: switches) {
- ClusterDFS cdfs = new ClusterDFS();
- dfsList.put(key, cdfs);
- }
- Set<Long> currSet = new HashSet<Long>();
-
- for (Long sw: switches) {
- ClusterDFS cdfs = dfsList.get(sw);
- if (cdfs == null) {
- log.error("No DFS object for switch {} found.", sw);
- }else if (!cdfs.isVisited()) {
- dfsTraverse(0, 1, sw, dfsList, currSet);
- }
- }
- }
-
-
- /**
- * @author Srinivasan Ramasubramanian
- *
- * This algorithm computes the depth first search (DFS) traversal of the
- * switches in the network, computes the lowpoint, and creates clusters
- * (of strongly connected components).
- *
- * The computation of strongly connected components is based on
- * Tarjan's algorithm. For more details, please see the Wikipedia
- * link below.
- *
- * http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
- *
- * The initialization of lowpoint and the check condition for when a
- * cluster should be formed is modified as we do not remove switches that
- * are already part of a cluster.
- *
- * A return value of -1 indicates that dfsTraverse failed somewhere in the middle
- * of computation. This could happen when a switch is removed during the cluster
- * computation procedure.
- *
- * @param parentIndex: DFS index of the parent node
- * @param currIndex: DFS index to be assigned to a newly visited node
- * @param currSw: ID of the current switch
- * @param dfsList: HashMap of DFS data structure for each switch
- * @param currSet: Set of nodes in the current cluster in formation
- * @return long: DSF index to be used when a new node is visited
- */
-
- private long dfsTraverse (long parentIndex, long currIndex, long currSw,
- Map<Long, ClusterDFS> dfsList, Set <Long> currSet) {
-
- //Get the DFS object corresponding to the current switch
- ClusterDFS currDFS = dfsList.get(currSw);
- // Get all the links corresponding to this switch
-
-
- //Assign the DFS object with right values.
- currDFS.setVisited(true);
- currDFS.setDfsIndex(currIndex);
- currDFS.setParentDFSIndex(parentIndex);
- currIndex++;
-
- // Traverse the graph through every outgoing link.
- if (switchPorts.get(currSw) != null){
- for(Short p: switchPorts.get(currSw)) {
- Set<Link> lset = switchPortLinks.get(new NodePortTuple(currSw, p));
- if (lset == null) continue;
- for(Link l:lset) {
- long dstSw = l.getDst();
-
- // ignore incoming links.
- if (dstSw == currSw) continue;
-
- // ignore if the destination is already added to
- // another cluster
- if (switchClusterMap.get(dstSw) != null) continue;
-
- // ignore the link if it is blocked.
- if (isBlockedLink(l)) continue;
-
- // ignore this link if it is in broadcast domain
- if (isBroadcastDomainLink(l)) continue;
-
- // Get the DFS object corresponding to the dstSw
- ClusterDFS dstDFS = dfsList.get(dstSw);
-
- if (dstDFS.getDfsIndex() < currDFS.getDfsIndex()) {
- // could be a potential lowpoint
- if (dstDFS.getDfsIndex() < currDFS.getLowpoint())
- currDFS.setLowpoint(dstDFS.getDfsIndex());
-
- } else if (!dstDFS.isVisited()) {
- // make a DFS visit
- currIndex = dfsTraverse(currDFS.getDfsIndex(), currIndex, dstSw,
- dfsList, currSet);
-
- if (currIndex < 0) return -1;
-
- // update lowpoint after the visit
- if (dstDFS.getLowpoint() < currDFS.getLowpoint())
- currDFS.setLowpoint(dstDFS.getLowpoint());
- }
- // else, it is a node already visited with a higher
- // dfs index, just ignore.
- }
- }
- }
-
- // Add current node to currSet.
- currSet.add(currSw);
-
- // Cluster computation.
- // If the node's lowpoint is greater than its parent's DFS index,
- // we need to form a new cluster with all the switches in the
- // currSet.
- if (currDFS.getLowpoint() > currDFS.getParentDFSIndex()) {
- // The cluster thus far forms a strongly connected component.
- // create a new switch cluster and the switches in the current
- // set to the switch cluster.
- Cluster sc = new Cluster();
- for(long sw: currSet){
- sc.add(sw);
- switchClusterMap.put(sw, sc);
- }
- // delete all the nodes in the current set.
- currSet.clear();
- // add the newly formed switch clusters to the cluster set.
- clusters.add(sc);
- }
-
- return currIndex;
- }
-
- /**
- * Go through every link and identify it is a blocked link or not.
- * If blocked, remove it from the switchport links and put them in the
- * blocked link category.
- *
- * Note that we do not update the tunnel ports and broadcast domain
- * port structures. We need those to still answer the question if the
- * ports are tunnel or broadcast domain ports.
- *
- * If we add additional ports to blocked ports later on, we may simply
- * call this method again to remove the links on the newly blocked ports.
- */
- protected void removeLinksOnBlockedPorts() {
- Iterator<NodePortTuple> nptIter;
- Iterator<Link> linkIter;
-
- // Iterate through all the links and all the switch ports
- // and move the links on blocked switch ports to blocked links
- nptIter = this.switchPortLinks.keySet().iterator();
- while (nptIter.hasNext()) {
- NodePortTuple npt = nptIter.next();
- linkIter = switchPortLinks.get(npt).iterator();
- while (linkIter.hasNext()) {
- Link link = linkIter.next();
- if (isBlockedLink(link)) {
- this.blockedLinks.add(link);
- linkIter.remove();
- }
- }
- // Note that at this point, the switchport may have
- // no links in it. We could delete the switch port,
- // but we will leave it as is.
- }
- }
-
- public Set<NodePortTuple> getBlockedPorts() {
- return this.blockedPorts;
- }
-
- protected Set<Link> getBlockedLinks() {
- return this.blockedLinks;
- }
-
- /** Returns true if a link has either one of its switch ports
- * blocked.
- * @param l
- * @return
- */
- protected boolean isBlockedLink(Link l) {
- NodePortTuple n1 = new NodePortTuple(l.getSrc(), l.getSrcPort());
- NodePortTuple n2 = new NodePortTuple(l.getDst(), l.getDstPort());
- return (isBlockedPort(n1) || isBlockedPort(n2));
- }
-
- protected boolean isBlockedPort(NodePortTuple npt) {
- return blockedPorts.contains(npt);
- }
-
- protected boolean isTunnelPort(NodePortTuple npt) {
- return tunnelPorts.contains(npt);
- }
-
- protected boolean isTunnelLink(Link l) {
- NodePortTuple n1 = new NodePortTuple(l.getSrc(), l.getSrcPort());
- NodePortTuple n2 = new NodePortTuple(l.getDst(), l.getDstPort());
- return (isTunnelPort(n1) || isTunnelPort(n2));
- }
-
- public boolean isBroadcastDomainLink(Link l) {
- NodePortTuple n1 = new NodePortTuple(l.getSrc(), l.getSrcPort());
- NodePortTuple n2 = new NodePortTuple(l.getDst(), l.getDstPort());
- return (isBroadcastDomainPort(n1) || isBroadcastDomainPort(n2));
- }
-
- public boolean isBroadcastDomainPort(NodePortTuple npt) {
- return broadcastDomainPorts.contains(npt);
- }
-
- class NodeDist implements Comparable<NodeDist> {
- private Long node;
- public Long getNode() {
- return node;
- }
-
- private int dist;
- public int getDist() {
- return dist;
- }
-
- public NodeDist(Long node, int dist) {
- this.node = node;
- this.dist = dist;
- }
-
- public int compareTo(NodeDist o) {
- if (o.dist == this.dist) {
- return (int)(o.node - this.node);
- }
- return o.dist - this.dist;
- }
- }
-
- protected BroadcastTree dijkstra(Cluster c, Long root,
- Map<Link, Integer> linkCost,
- boolean isDstRooted) {
- HashMap<Long, Link> nexthoplinks = new HashMap<Long, Link>();
- //HashMap<Long, Long> nexthopnodes = new HashMap<Long, Long>();
- HashMap<Long, Integer> cost = new HashMap<Long, Integer>();
- int w;
-
- for (Long node: c.links.keySet()) {
- nexthoplinks.put(node, null);
- //nexthopnodes.put(node, null);
- cost.put(node, MAX_PATH_WEIGHT);
- }
-
- HashMap<Long, Boolean> seen = new HashMap<Long, Boolean>();
- PriorityQueue<NodeDist> nodeq = new PriorityQueue<NodeDist>();
- nodeq.add(new NodeDist(root, 0));
- cost.put(root, 0);
- while (nodeq.peek() != null) {
- NodeDist n = nodeq.poll();
- Long cnode = n.getNode();
- int cdist = n.getDist();
- if (cdist >= MAX_PATH_WEIGHT) break;
- if (seen.containsKey(cnode)) continue;
- seen.put(cnode, true);
-
- for (Link link: c.links.get(cnode)) {
- Long neighbor;
-
- if (isDstRooted == true) neighbor = link.getSrc();
- else neighbor = link.getDst();
-
- // links directed toward cnode will result in this condition
- // if (neighbor == cnode) continue;
-
- if (linkCost == null || linkCost.get(link)==null) w = 1;
- else w = linkCost.get(link);
-
- int ndist = cdist + w; // the weight of the link, always 1 in current version of floodlight.
- if (ndist < cost.get(neighbor)) {
- cost.put(neighbor, ndist);
- nexthoplinks.put(neighbor, link);
- //nexthopnodes.put(neighbor, cnode);
- nodeq.add(new NodeDist(neighbor, ndist));
- }
- }
- }
-
- BroadcastTree ret = new BroadcastTree(nexthoplinks, cost);
- return ret;
- }
-
- protected void calculateShortestPathTreeInClusters() {
- pathcache.clear();
- destinationRootedTrees.clear();
-
- Map<Link, Integer> linkCost = new HashMap<Link, Integer>();
- int tunnel_weight = switchPorts.size() + 1;
-
- for(NodePortTuple npt: tunnelPorts) {
- if (switchPortLinks.get(npt) == null) continue;
- for(Link link: switchPortLinks.get(npt)) {
- if (link == null) continue;
- linkCost.put(link, tunnel_weight);
- }
- }
-
- for(Cluster c: clusters) {
- for (Long node : c.links.keySet()) {
- BroadcastTree tree = dijkstra(c, node, linkCost, true);
- destinationRootedTrees.put(node, tree);
- }
- }
- }
-
- protected void calculateBroadcastTreeInClusters() {
- for(Cluster c: clusters) {
- // c.id is the smallest node that's in the cluster
- BroadcastTree tree = destinationRootedTrees.get(c.id);
- clusterBroadcastTrees.put(c.id, tree);
- }
- }
-
- protected void calculateBroadcastNodePortsInClusters() {
-
- clusterBroadcastTrees.clear();
-
- calculateBroadcastTreeInClusters();
-
- for(Cluster c: clusters) {
- // c.id is the smallest node that's in the cluster
- BroadcastTree tree = clusterBroadcastTrees.get(c.id);
- //log.info("Broadcast Tree {}", tree);
-
- Set<NodePortTuple> nptSet = new HashSet<NodePortTuple>();
- Map<Long, Link> links = tree.getLinks();
- if (links == null) continue;
- for(long nodeId: links.keySet()) {
- Link l = links.get(nodeId);
- if (l == null) continue;
- NodePortTuple npt1 = new NodePortTuple(l.getSrc(), l.getSrcPort());
- NodePortTuple npt2 = new NodePortTuple(l.getDst(), l.getDstPort());
- nptSet.add(npt1);
- nptSet.add(npt2);
- }
- clusterBroadcastNodePorts.put(c.id, nptSet);
- }
- }
-
- protected Route buildroute(RouteId id, long srcId, long dstId) {
- NodePortTuple npt;
-
- LinkedList<NodePortTuple> switchPorts =
- new LinkedList<NodePortTuple>();
-
- if (destinationRootedTrees == null) return null;
- if (destinationRootedTrees.get(dstId) == null) return null;
-
- Map<Long, Link> nexthoplinks =
- destinationRootedTrees.get(dstId).getLinks();
-
- if (!switches.contains(srcId) || !switches.contains(dstId)) {
- // This is a switch that is not connected to any other switch
- // hence there was no update for links (and hence it is not
- // in the network)
- log.debug("buildroute: Standalone switch: {}", srcId);
-
- // The only possible non-null path for this case is
- // if srcId equals dstId --- and that too is an 'empty' path []
-
- } else if ((nexthoplinks!=null) && (nexthoplinks.get(srcId)!=null)) {
- while (srcId != dstId) {
- Link l = nexthoplinks.get(srcId);
-
- npt = new NodePortTuple(l.getSrc(), l.getSrcPort());
- switchPorts.addLast(npt);
- npt = new NodePortTuple(l.getDst(), l.getDstPort());
- switchPorts.addLast(npt);
- srcId = nexthoplinks.get(srcId).getDst();
- }
- }
- // else, no path exists, and path equals null
-
- Route result = null;
- if (switchPorts != null && !switchPorts.isEmpty())
- result = new Route(id, switchPorts);
- if (log.isTraceEnabled()) {
- log.trace("buildroute: {}", result);
- }
- return result;
- }
-
- protected int getCost(long srcId, long dstId) {
- BroadcastTree bt = destinationRootedTrees.get(dstId);
- if (bt == null) return -1;
- return (bt.getCost(srcId));
- }
-
- /*
- * Getter Functions
- */
-
- protected Set<Cluster> getClusters() {
- return clusters;
- }
-
- // IRoutingEngineService interfaces
- protected boolean routeExists(long srcId, long dstId) {
- BroadcastTree bt = destinationRootedTrees.get(dstId);
- if (bt == null) return false;
- Link link = bt.getLinks().get(srcId);
- if (link == null) return false;
- return true;
- }
-
- protected Route getRoute(long srcId, short srcPort,
- long dstId, short dstPort) {
-
-
- // Return null the route source and desitnation are the
- // same switchports.
- if (srcId == dstId && srcPort == dstPort)
- return null;
-
- List<NodePortTuple> nptList;
- NodePortTuple npt;
- Route r = getRoute(srcId, dstId);
- if (r == null && srcId != dstId) return null;
-
- if (r != null) {
- nptList= new ArrayList<NodePortTuple>(r.getPath());
- } else {
- nptList = new ArrayList<NodePortTuple>();
- }
- npt = new NodePortTuple(srcId, srcPort);
- nptList.add(0, npt); // add src port to the front
- npt = new NodePortTuple(dstId, dstPort);
- nptList.add(npt); // add dst port to the end
-
- RouteId id = new RouteId(srcId, dstId);
- r = new Route(id, nptList);
- return r;
- }
-
- protected Route getRoute(long srcId, long dstId) {
- RouteId id = new RouteId(srcId, dstId);
- Route result = null;
- if (pathcache.containsKey(id)) {
- result = pathcache.get(id);
- } else {
- result = buildroute(id, srcId, dstId);
- pathcache.put(id, result);
- }
- if (log.isTraceEnabled()) {
- log.trace("getRoute: {} -> {}", id, result);
- }
- return result;
- }
-
- protected BroadcastTree getBroadcastTreeForCluster(long clusterId){
- Cluster c = switchClusterMap.get(clusterId);
- if (c == null) return null;
- return clusterBroadcastTrees.get(c.id);
- }
-
- //
- // ITopologyService interface method helpers.
- //
-
- protected boolean isInternalToOpenflowDomain(long switchid, short port) {
- return !isAttachmentPointPort(switchid, port);
- }
-
- public boolean isAttachmentPointPort(long switchid, short port) {
- NodePortTuple npt = new NodePortTuple(switchid, port);
- if (switchPortLinks.containsKey(npt)) return false;
- return true;
- }
-
- protected long getOpenflowDomainId(long switchId) {
- Cluster c = switchClusterMap.get(switchId);
- if (c == null) return switchId;
- return c.getId();
- }
-
- protected long getL2DomainId(long switchId) {
- return getOpenflowDomainId(switchId);
- }
-
- protected Set<Long> getSwitchesInOpenflowDomain(long switchId) {
- Cluster c = switchClusterMap.get(switchId);
- if (c == null) return null;
- return (c.getNodes());
- }
-
- protected boolean inSameOpenflowDomain(long switch1, long switch2) {
- Cluster c1 = switchClusterMap.get(switch1);
- Cluster c2 = switchClusterMap.get(switch2);
- if (c1 != null && c2 != null)
- return (c1.getId() == c2.getId());
- return (switch1 == switch2);
- }
-
- public boolean isAllowed(long sw, short portId) {
- return true;
- }
-
- protected boolean
- isIncomingBroadcastAllowedOnSwitchPort(long sw, short portId) {
- if (isInternalToOpenflowDomain(sw, portId)) {
- long clusterId = getOpenflowDomainId(sw);
- NodePortTuple npt = new NodePortTuple(sw, portId);
- if (clusterBroadcastNodePorts.get(clusterId).contains(npt))
- return true;
- else return false;
- }
- return true;
- }
-
- public boolean isConsistent(long oldSw, short oldPort, long newSw,
- short newPort) {
- if (isInternalToOpenflowDomain(newSw, newPort)) return true;
- return (oldSw == newSw && oldPort == newPort);
- }
-
- protected Set<NodePortTuple>
- getBroadcastNodePortsInCluster(long sw) {
- long clusterId = getOpenflowDomainId(sw);
- return clusterBroadcastNodePorts.get(clusterId);
- }
-
- public boolean inSameBroadcastDomain(long s1, short p1, long s2, short p2) {
- return false;
- }
-
- public boolean inSameL2Domain(long switch1, long switch2) {
- return inSameOpenflowDomain(switch1, switch2);
- }
-
- public NodePortTuple getOutgoingSwitchPort(long src, short srcPort,
- long dst, short dstPort) {
- // Use this function to redirect traffic if needed.
- return new NodePortTuple(dst, dstPort);
- }
-
- public NodePortTuple getIncomingSwitchPort(long src, short srcPort,
- long dst, short dstPort) {
- // Use this function to reinject traffic from a different port if needed.
- return new NodePortTuple(src, srcPort);
- }
-
- public Set<Long> getSwitches() {
- return switches;
- }
-
- public Set<Short> getPortsWithLinks(long sw) {
- return switchPorts.get(sw);
- }
-
- public Set<Short> getBroadcastPorts(long targetSw, long src, short srcPort) {
- Set<Short> result = new HashSet<Short>();
- long clusterId = getOpenflowDomainId(targetSw);
- for(NodePortTuple npt: clusterBroadcastNodePorts.get(clusterId)) {
- if (npt.getNodeId() == targetSw) {
- result.add(npt.getPortId());
- }
- }
- return result;
- }
-
- public NodePortTuple
- getAllowedOutgoingBroadcastPort(long src, short srcPort, long dst,
- short dstPort) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public NodePortTuple
- getAllowedIncomingBroadcastPort(long src, short srcPort) {
- // TODO Auto-generated method stub
- return null;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
deleted file mode 100644
index 103cc4d..0000000
--- a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
+++ /dev/null
@@ -1,1133 +0,0 @@
-package net.floodlightcontroller.topology;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.util.SingletonTask;
-import net.floodlightcontroller.packet.BSN;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.LLDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.IRoutingService;
-import net.floodlightcontroller.routing.Link;
-import net.floodlightcontroller.routing.Route;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.web.TopologyWebRoutable;
-import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
-import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Topology manager is responsible for maintaining the controller's notion
- * of the network graph, as well as implementing tools for finding routes
- * through the topology.
- */
-@LogMessageCategory("Network Topology")
-public class TopologyManager implements
- IFloodlightModule, ITopologyService,
- IRoutingService, ILinkDiscoveryListener,
- IOFMessageListener {
-
- protected final static Logger log = LoggerFactory.getLogger(TopologyManager.class);
-
- public static final String CONTEXT_TUNNEL_ENABLED =
- "com.bigswitch.floodlight.topologymanager.tunnelEnabled";
-
- /**
- * Set of ports for each switch
- */
- protected Map<Long, Set<Short>> switchPorts;
-
- /**
- * Set of links organized by node port tuple
- */
- protected Map<NodePortTuple, Set<Link>> switchPortLinks;
-
- /**
- * Set of direct links
- */
- protected Map<NodePortTuple, Set<Link>> directLinks;
-
- /**
- * set of links that are broadcast domain links.
- */
- protected Map<NodePortTuple, Set<Link>> portBroadcastDomainLinks;
-
- /**
- * set of tunnel links
- */
- protected Map<NodePortTuple, Set<Link>> tunnelLinks;
-
- protected ILinkDiscoveryService linkDiscovery;
- protected IThreadPoolService threadPool;
- protected IFloodlightProviderService floodlightProvider;
- protected IRestApiService restApi;
-
- // Modules that listen to our updates
- protected ArrayList<ITopologyListener> topologyAware;
-
- protected BlockingQueue<LDUpdate> ldUpdates;
- protected List<LDUpdate> appliedUpdates;
-
- // These must be accessed using getCurrentInstance(), not directly
- protected TopologyInstance currentInstance;
- protected TopologyInstance currentInstanceWithoutTunnels;
-
- protected SingletonTask newInstanceTask;
- private Date lastUpdateTime;
-
- /**
- * Flag that indicates if links (direct/tunnel/multihop links) were
- * updated as part of LDUpdate.
- */
- protected boolean linksUpdated;
- /**
- * Flag that indicates if direct or tunnel links were updated as
- * part of LDUpdate.
- */
- protected boolean dtLinksUpdated;
-
- /**
- * Thread for recomputing topology. The thread is always running,
- * however the function applyUpdates() has a blocking call.
- */
- @LogMessageDoc(level="ERROR",
- message="Error in topology instance task thread",
- explanation="An unknown error occured in the topology " +
- "discovery module.",
- recommendation=LogMessageDoc.CHECK_CONTROLLER)
- protected class UpdateTopologyWorker implements Runnable {
- @Override
- public void run() {
- try {
- updateTopology();
- }
- catch (Exception e) {
- log.error("Error in topology instance task thread", e);
- }
- }
- }
-
- public boolean updateTopology() {
- boolean newInstanceFlag;
- linksUpdated = false;
- dtLinksUpdated = false;
- applyUpdates();
- newInstanceFlag = createNewInstance();
- lastUpdateTime = new Date();
- informListeners();
- return newInstanceFlag;
- }
-
- // **********************
- // ILinkDiscoveryListener
- // **********************
-
- @Override
- public void linkDiscoveryUpdate(LDUpdate update) {
- boolean scheduleFlag = false;
- // if there's no udpates in the queue, then
- // we need to schedule an update.
- if (ldUpdates.peek() == null)
- scheduleFlag = true;
-
- if (log.isTraceEnabled()) {
- log.trace("Queuing update: {}", update);
- }
- ldUpdates.add(update);
-
- if (scheduleFlag) {
- newInstanceTask.reschedule(1, TimeUnit.MICROSECONDS);
- }
- }
-
- // ****************
- // ITopologyService
- // ****************
-
- //
- // ITopologyService interface methods
- //
- @Override
- public Date getLastUpdateTime() {
- return lastUpdateTime;
- }
-
- @Override
- public void addListener(ITopologyListener listener) {
- topologyAware.add(listener);
- }
-
- @Override
- public boolean isAttachmentPointPort(long switchid, short port) {
- return isAttachmentPointPort(switchid, port, true);
- }
-
- @Override
- public boolean isAttachmentPointPort(long switchid, short port,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
-
- // if the port is not attachment point port according to
- // topology instance, then return false
- if (ti.isAttachmentPointPort(switchid, port) == false)
- return false;
-
- // Check whether the port is a physical port. We should not learn
- // attachment points on "special" ports.
- if ((port & 0xff00) == 0xff00 && port != (short)0xfffe) return false;
-
- // Make sure that the port is enabled.
- IOFSwitch sw = floodlightProvider.getSwitches().get(switchid);
- if (sw == null) return false;
- return (sw.portEnabled(port));
- }
-
- public long getOpenflowDomainId(long switchId) {
- return getOpenflowDomainId(switchId, true);
- }
-
- public long getOpenflowDomainId(long switchId, boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getOpenflowDomainId(switchId);
- }
-
- @Override
- public long getL2DomainId(long switchId) {
- return getL2DomainId(switchId, true);
- }
-
- @Override
- public long getL2DomainId(long switchId, boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getL2DomainId(switchId);
- }
-
- @Override
- public boolean inSameOpenflowDomain(long switch1, long switch2) {
- return inSameOpenflowDomain(switch1, switch2, true);
- }
-
- @Override
- public boolean inSameOpenflowDomain(long switch1, long switch2,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.inSameOpenflowDomain(switch1, switch2);
- }
-
- @Override
- public boolean isAllowed(long sw, short portId) {
- return isAllowed(sw, portId, true);
- }
-
- @Override
- public boolean isAllowed(long sw, short portId, boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.isAllowed(sw, portId);
- }
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- @Override
- public boolean isIncomingBroadcastAllowed(long sw, short portId) {
- return isIncomingBroadcastAllowed(sw, portId, true);
- }
-
- public boolean isIncomingBroadcastAllowed(long sw, short portId,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.isIncomingBroadcastAllowedOnSwitchPort(sw, portId);
- }
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- /** Get all the ports connected to the switch */
- @Override
- public Set<Short> getPortsWithLinks(long sw) {
- return getPortsWithLinks(sw, true);
- }
-
- /** Get all the ports connected to the switch */
- @Override
- public Set<Short> getPortsWithLinks(long sw, boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getPortsWithLinks(sw);
- }
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- /** Get all the ports on the target switch (targetSw) on which a
- * broadcast packet must be sent from a host whose attachment point
- * is on switch port (src, srcPort).
- */
- public Set<Short> getBroadcastPorts(long targetSw,
- long src, short srcPort) {
- return getBroadcastPorts(targetSw, src, srcPort, true);
- }
-
- /** Get all the ports on the target switch (targetSw) on which a
- * broadcast packet must be sent from a host whose attachment point
- * is on switch port (src, srcPort).
- */
- public Set<Short> getBroadcastPorts(long targetSw,
- long src, short srcPort,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getBroadcastPorts(targetSw, src, srcPort);
- }
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- @Override
- public NodePortTuple getOutgoingSwitchPort(long src, short srcPort,
- long dst, short dstPort) {
- // Use this function to redirect traffic if needed.
- return getOutgoingSwitchPort(src, srcPort, dst, dstPort, true);
- }
-
- @Override
- public NodePortTuple getOutgoingSwitchPort(long src, short srcPort,
- long dst, short dstPort,
- boolean tunnelEnabled) {
- // Use this function to redirect traffic if needed.
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getOutgoingSwitchPort(src, srcPort,
- dst, dstPort);
- }
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- @Override
- public NodePortTuple getIncomingSwitchPort(long src, short srcPort,
- long dst, short dstPort) {
- return getIncomingSwitchPort(src, srcPort, dst, dstPort, true);
- }
-
- @Override
- public NodePortTuple getIncomingSwitchPort(long src, short srcPort,
- long dst, short dstPort,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getIncomingSwitchPort(src, srcPort,
- dst, dstPort);
- }
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- /**
- * Checks if the two switchports belong to the same broadcast domain.
- */
- @Override
- public boolean isInSameBroadcastDomain(long s1, short p1, long s2,
- short p2) {
- return isInSameBroadcastDomain(s1, p1, s2, p2, true);
-
- }
-
- @Override
- public boolean isInSameBroadcastDomain(long s1, short p1,
- long s2, short p2,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.inSameBroadcastDomain(s1, p1, s2, p2);
-
- }
-
-
- /**
- * Checks if the switchport is a broadcast domain port or not.
- */
- @Override
- public boolean isBroadcastDomainPort(long sw, short port) {
- return isBroadcastDomainPort(sw, port, true);
- }
-
- @Override
- public boolean isBroadcastDomainPort(long sw, short port,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.isBroadcastDomainPort(new NodePortTuple(sw, port));
- }
-
-
- /**
- * Checks if the new attachment point port is consistent with the
- * old attachment point port.
- */
- @Override
- public boolean isConsistent(long oldSw, short oldPort,
- long newSw, short newPort) {
- return isConsistent(oldSw, oldPort,
- newSw, newPort, true);
- }
-
- @Override
- public boolean isConsistent(long oldSw, short oldPort,
- long newSw, short newPort,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.isConsistent(oldSw, oldPort, newSw, newPort);
- }
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- /**
- * Checks if the two switches are in the same Layer 2 domain.
- */
- @Override
- public boolean inSameL2Domain(long switch1, long switch2) {
- return inSameL2Domain(switch1, switch2, true);
- }
-
- @Override
- public boolean inSameL2Domain(long switch1, long switch2,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.inSameL2Domain(switch1, switch2);
- }
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- @Override
- public NodePortTuple getAllowedOutgoingBroadcastPort(long src,
- short srcPort,
- long dst,
- short dstPort) {
- return getAllowedOutgoingBroadcastPort(src, srcPort,
- dst, dstPort, true);
- }
-
- @Override
- public NodePortTuple getAllowedOutgoingBroadcastPort(long src,
- short srcPort,
- long dst,
- short dstPort,
- boolean tunnelEnabled){
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getAllowedOutgoingBroadcastPort(src, srcPort,
- dst, dstPort);
- }
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- @Override
- public NodePortTuple
- getAllowedIncomingBroadcastPort(long src, short srcPort) {
- return getAllowedIncomingBroadcastPort(src,srcPort, true);
- }
-
- @Override
- public NodePortTuple
- getAllowedIncomingBroadcastPort(long src, short srcPort,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getAllowedIncomingBroadcastPort(src,srcPort);
- }
-
- @Override
- public Set<NodePortTuple> getBroadcastDomainPorts() {
- return portBroadcastDomainLinks.keySet();
- }
-
- @Override
- public Set<NodePortTuple> getTunnelPorts() {
- return tunnelLinks.keySet();
- }
-
- @Override
- public Set<NodePortTuple> getBlockedPorts() {
- Set<NodePortTuple> bp;
- Set<NodePortTuple> blockedPorts =
- new HashSet<NodePortTuple>();
-
- // As we might have two topologies, simply get the union of
- // both of them and send it.
- bp = getCurrentInstance(true).getBlockedPorts();
- if (bp != null)
- blockedPorts.addAll(bp);
-
- bp = getCurrentInstance(false).getBlockedPorts();
- if (bp != null)
- blockedPorts.addAll(bp);
-
- return blockedPorts;
- }
-
- @Override
- public List<LDUpdate> getLastLinkUpdates() {
- return appliedUpdates;
- }
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
-
- // ***************
- // IRoutingService
- // ***************
-
- @Override
- public Route getRoute(long src, long dst) {
- return getRoute(src, dst, true);
- }
-
- @Override
- public Route getRoute(long src, long dst, boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getRoute(src, dst);
- }
-
- @Override
- public Route getRoute(long src, short srcPort, long dst, short dstPort) {
- return getRoute(src, srcPort, dst, dstPort, true);
- }
-
- @Override
- public Route getRoute(long src, short srcPort, long dst, short dstPort,
- boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.getRoute(src, srcPort, dst, dstPort);
- }
-
- @Override
- public boolean routeExists(long src, long dst) {
- return routeExists(src, dst, true);
- }
-
- @Override
- public boolean routeExists(long src, long dst, boolean tunnelEnabled) {
- TopologyInstance ti = getCurrentInstance(tunnelEnabled);
- return ti.routeExists(src, dst);
- }
-
-
- // ******************
- // IOFMessageListener
- // ******************
-
- @Override
- public String getName() {
- return "topology";
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return "linkdiscovery".equals(name);
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return false;
- }
-
- @Override
- public Command receive(IOFSwitch sw, OFMessage msg,
- FloodlightContext cntx) {
- switch (msg.getType()) {
- case PACKET_IN:
- return this.processPacketInMessage(sw,
- (OFPacketIn) msg, cntx);
- default:
- break;
- }
-
- return Command.CONTINUE;
- }
-
- // *****************
- // IFloodlightModule
- // *****************
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(ITopologyService.class);
- l.add(IRoutingService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- // We are the class that implements the service
- m.put(ITopologyService.class, this);
- m.put(IRoutingService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>>
- getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(ILinkDiscoveryService.class);
- l.add(IThreadPoolService.class);
- l.add(IFloodlightProviderService.class);
- l.add(IRestApiService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
- threadPool = context.getServiceImpl(IThreadPoolService.class);
- floodlightProvider =
- context.getServiceImpl(IFloodlightProviderService.class);
- restApi = context.getServiceImpl(IRestApiService.class);
-
- switchPorts = new HashMap<Long,Set<Short>>();
- switchPortLinks = new HashMap<NodePortTuple, Set<Link>>();
- directLinks = new HashMap<NodePortTuple, Set<Link>>();
- portBroadcastDomainLinks = new HashMap<NodePortTuple, Set<Link>>();
- tunnelLinks = new HashMap<NodePortTuple, Set<Link>>();
- topologyAware = new ArrayList<ITopologyListener>();
- ldUpdates = new LinkedBlockingQueue<LDUpdate>();
- appliedUpdates = new ArrayList<LDUpdate>();
- clearCurrentTopology();
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- ScheduledExecutorService ses = threadPool.getScheduledExecutor();
- newInstanceTask = new SingletonTask(ses, new UpdateTopologyWorker());
- linkDiscovery.addListener(this);
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- addRestletRoutable();
- }
-
- protected void addRestletRoutable() {
- restApi.addRestletRoutable(new TopologyWebRoutable());
- }
-
- // ****************
- // Internal methods
- // ****************
- /**
- * If the packet-in switch port is disabled for all data traffic, then
- * the packet will be dropped. Otherwise, the packet will follow the
- * normal processing chain.
- * @param sw
- * @param pi
- * @param cntx
- * @return
- */
- protected Command dropFilter(long sw, OFPacketIn pi,
- FloodlightContext cntx) {
- Command result = Command.CONTINUE;
- short port = pi.getInPort();
-
- // If the input port is not allowed for data traffic, drop everything.
- // BDDP packets will not reach this stage.
- if (isAllowed(sw, port) == false) {
- if (log.isTraceEnabled()) {
- log.trace("Ignoring packet because of topology " +
- "restriction on switch={}, port={}", sw, port);
- result = Command.STOP;
- }
- }
-
- // if sufficient information is available, then drop broadcast
- // packets here as well.
- return result;
- }
-
- /**
- * TODO This method must be moved to a layer below forwarding
- * so that anyone can use it.
- * @param packetData
- * @param sw
- * @param ports
- * @param cntx
- */
- @LogMessageDoc(level="ERROR",
- message="Failed to clear all flows on switch {switch}",
- explanation="An I/O error occured while trying send " +
- "topology discovery packet",
- recommendation=LogMessageDoc.CHECK_SWITCH)
- public void doMultiActionPacketOut(byte[] packetData, IOFSwitch sw,
- Set<Short> ports,
- FloodlightContext cntx) {
-
- if (ports == null) return;
- if (packetData == null || packetData.length <= 0) return;
-
- OFPacketOut po =
- (OFPacketOut) floodlightProvider.getOFMessageFactory().
- getMessage(OFType.PACKET_OUT);
-
- List<OFAction> actions = new ArrayList<OFAction>();
- for(short p: ports) {
- actions.add(new OFActionOutput(p, (short) 0));
- }
-
- // set actions
- po.setActions(actions);
- // set action length
- po.setActionsLength((short) (OFActionOutput.MINIMUM_LENGTH *
- ports.size()));
- // set buffer-id to BUFFER_ID_NONE
- po.setBufferId(OFPacketOut.BUFFER_ID_NONE);
- // set in-port to OFPP_NONE
- po.setInPort(OFPort.OFPP_NONE.getValue());
-
- // set packet data
- po.setPacketData(packetData);
-
- // compute and set packet length.
- short poLength = (short)(OFPacketOut.MINIMUM_LENGTH +
- po.getActionsLength() +
- packetData.length);
-
- po.setLength(poLength);
-
- try {
- //counterStore.updatePktOutFMCounterStore(sw, po);
- if (log.isTraceEnabled()) {
- log.trace("write broadcast packet on switch-id={} " +
- "interaces={} packet-data={} packet-out={}",
- new Object[] {sw.getId(), ports, packetData, po});
- }
- sw.write(po, cntx);
-
- } catch (IOException e) {
- log.error("Failure writing packet out", e);
- }
- }
-
-
- /**
- * The BDDP packets are forwarded out of all the ports out of an
- * openflowdomain. Get all the switches in the same openflow
- * domain as the sw (disabling tunnels). Then get all the
- * external switch ports and send these packets out.
- * @param sw
- * @param pi
- * @param cntx
- */
- protected void doFloodBDDP(long pinSwitch, OFPacketIn pi,
- FloodlightContext cntx) {
-
- TopologyInstance ti = getCurrentInstance(false);
-
- Set<Long> switches = ti.getSwitchesInOpenflowDomain(pinSwitch);
-
- if (switches == null)
- {
- // indicates no links are connected to the switches
- switches = new HashSet<Long>();
- switches.add(pinSwitch);
- }
-
- for(long sid: switches) {
- IOFSwitch sw = floodlightProvider.getSwitches().get(sid);
- if (sw == null) continue;
- Collection<Short> enabledPorts = sw.getEnabledPortNumbers();
- if (enabledPorts == null)
- continue;
- Set<Short> ports = new HashSet<Short>();
- ports.addAll(enabledPorts);
-
- // all the ports known to topology // without tunnels.
- // out of these, we need to choose only those that are
- // broadcast port, otherwise, we should eliminate.
- Set<Short> portsKnownToTopo = ti.getPortsWithLinks(sid);
-
- if (portsKnownToTopo != null) {
- for(short p: portsKnownToTopo) {
- NodePortTuple npt =
- new NodePortTuple(sid, p);
- if (ti.isBroadcastDomainPort(npt) == false) {
- ports.remove(p);
- }
- }
- }
-
- // remove the incoming switch port
- if (pinSwitch == sid) {
- ports.remove(pi.getInPort());
- }
-
- // we have all the switch ports to which we need to broadcast.
- doMultiActionPacketOut(pi.getPacketData(), sw, ports, cntx);
- }
-
- }
-
- protected Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi,
- FloodlightContext cntx) {
-
- // get the packet-in switch.
- Ethernet eth =
- IFloodlightProviderService.bcStore.
- get(cntx,IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
- if (eth.getEtherType() == Ethernet.TYPE_BSN) {
- BSN bsn = (BSN) eth.getPayload();
- if (bsn == null) return Command.STOP;
- if (bsn.getPayload() == null) return Command.STOP;
-
- // It could be a packet other than BSN LLDP, therefore
- // continue with the regular processing.
- if (bsn.getPayload() instanceof LLDP == false)
- return Command.CONTINUE;
-
- doFloodBDDP(sw.getId(), pi, cntx);
- } else {
- return dropFilter(sw.getId(), pi, cntx);
- }
- return Command.STOP;
- }
-
-
- /**
- * Updates concerning switch disconnect and port down are not processed.
- * LinkDiscoveryManager is expected to process those messages and send
- * multiple link removed messages. However, all the updates from
- * LinkDiscoveryManager would be propagated to the listeners of topology.
- */
- @LogMessageDoc(level="ERROR",
- message="Error reading link discovery update.",
- explanation="Unable to process link discovery update",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
- public void applyUpdates() {
- appliedUpdates.clear();
- LDUpdate update = null;
- while (ldUpdates.peek() != null) {
- try {
- update = ldUpdates.take();
- } catch (Exception e) {
- log.error("Error reading link discovery update.", e);
- }
- if (log.isTraceEnabled()) {
- log.trace("Applying update: {}", update);
- }
- if (update.getOperation() == UpdateOperation.LINK_UPDATED ||
- update.getOperation() == UpdateOperation.LINK_ADDED ) {
- addOrUpdateLink(update.getSrc(), update.getSrcPort(),
- update.getDst(), update.getDstPort(),
- update.getType());
- } else if (update.getOperation() == UpdateOperation.LINK_REMOVED){
- removeLink(update.getSrc(), update.getSrcPort(),
- update.getDst(), update.getDstPort());
- }
- // Add to the list of applied updates.
- appliedUpdates.add(update);
- }
- }
-
- /**
- * This function computes a new topology.
- */
- /**
- * This function computes a new topology instance.
- * It ignores links connected to all broadcast domain ports
- * and tunnel ports. The method returns if a new instance of
- * topology was created or not.
- */
- protected boolean createNewInstance() {
- Set<NodePortTuple> blockedPorts = new HashSet<NodePortTuple>();
-
- if (!linksUpdated) return false;
-
- Map<NodePortTuple, Set<Link>> openflowLinks;
- openflowLinks =
- new HashMap<NodePortTuple, Set<Link>>(switchPortLinks);
-
- // Remove all tunnel links.
- for(NodePortTuple npt: tunnelLinks.keySet()) {
- if (openflowLinks.get(npt) != null)
- openflowLinks.remove(npt);
- }
-
- // Remove all broadcast domain links.
- for(NodePortTuple npt: portBroadcastDomainLinks.keySet()) {
- if (openflowLinks.get(npt) != null)
- openflowLinks.remove(npt);
- }
-
- TopologyInstance nt = new TopologyInstance(switchPorts,
- blockedPorts,
- openflowLinks,
- portBroadcastDomainLinks.keySet(),
- tunnelLinks.keySet());
- nt.compute();
- // We set the instances with and without tunnels to be identical.
- // If needed, we may compute them differently.
- currentInstance = nt;
- currentInstanceWithoutTunnels = nt;
- return true;
- }
-
-
- public void informListeners() {
- for(int i=0; i<topologyAware.size(); ++i) {
- ITopologyListener listener = topologyAware.get(i);
- listener.topologyChanged();
- }
- }
-
- public void addSwitch(long sid) {
- if (switchPorts.containsKey(sid) == false) {
- switchPorts.put(sid, new HashSet<Short>());
- }
- }
-
- private void addPortToSwitch(long s, short p) {
- addSwitch(s);
- switchPorts.get(s).add(p);
- }
-
- public boolean removeSwitchPort(long sw, short port) {
-
- Set<Link> linksToRemove = new HashSet<Link>();
- NodePortTuple npt = new NodePortTuple(sw, port);
- if (switchPortLinks.containsKey(npt) == false) return false;
-
- linksToRemove.addAll(switchPortLinks.get(npt));
- for(Link link: linksToRemove) {
- removeLink(link);
- }
- return true;
- }
-
- public boolean removeSwitch(long sid) {
- // Delete all the links in the switch, switch and all
- // associated data should be deleted.
- if (switchPorts.containsKey(sid) == false) return false;
-
- Set<Link> linksToRemove = new HashSet<Link>();
- for(Short p: switchPorts.get(sid)) {
- NodePortTuple n1 = new NodePortTuple(sid, p);
- linksToRemove.addAll(switchPortLinks.get(n1));
- }
-
- if (linksToRemove.isEmpty()) return false;
-
- for(Link link: linksToRemove) {
- removeLink(link);
- }
- return true;
- }
-
- /**
- * Add the given link to the data structure. Returns true if a link was
- * added.
- * @param s
- * @param l
- * @return
- */
- private boolean addLinkToStructure(Map<NodePortTuple,
- Set<Link>> s, Link l) {
- boolean result1 = false, result2 = false;
-
- NodePortTuple n1 = new NodePortTuple(l.getSrc(), l.getSrcPort());
- NodePortTuple n2 = new NodePortTuple(l.getDst(), l.getDstPort());
-
- if (s.get(n1) == null) {
- s.put(n1, new HashSet<Link>());
- }
- if (s.get(n2) == null) {
- s.put(n2, new HashSet<Link>());
- }
- result1 = s.get(n1).add(l);
- result2 = s.get(n2).add(l);
-
- return (result1 || result2);
- }
-
- /**
- * Delete the given link from the data strucure. Returns true if the
- * link was deleted.
- * @param s
- * @param l
- * @return
- */
- private boolean removeLinkFromStructure(Map<NodePortTuple,
- Set<Link>> s, Link l) {
-
- boolean result1 = false, result2 = false;
- NodePortTuple n1 = new NodePortTuple(l.getSrc(), l.getSrcPort());
- NodePortTuple n2 = new NodePortTuple(l.getDst(), l.getDstPort());
-
- if (s.get(n1) != null) {
- result1 = s.get(n1).remove(l);
- if (s.get(n1).isEmpty()) s.remove(n1);
- }
- if (s.get(n2) != null) {
- result2 = s.get(n2).remove(l);
- if (s.get(n2).isEmpty()) s.remove(n2);
- }
- return result1 || result2;
- }
-
- public void addOrUpdateLink(long srcId, short srcPort, long dstId,
- short dstPort, LinkType type) {
- boolean flag1 = false, flag2 = false;
-
- Link link = new Link(srcId, srcPort, dstId, dstPort);
- addPortToSwitch(srcId, srcPort);
- addPortToSwitch(dstId, dstPort);
-
- addLinkToStructure(switchPortLinks, link);
-
- if (type.equals(LinkType.MULTIHOP_LINK)) {
- addLinkToStructure(portBroadcastDomainLinks, link);
- flag1 = removeLinkFromStructure(tunnelLinks, link);
- flag2 = removeLinkFromStructure(directLinks, link);
- dtLinksUpdated = flag1 || flag2;
- } else if (type.equals(LinkType.TUNNEL)) {
- addLinkToStructure(tunnelLinks, link);
- removeLinkFromStructure(portBroadcastDomainLinks, link);
- removeLinkFromStructure(directLinks, link);
- dtLinksUpdated = true;
- } else if (type.equals(LinkType.DIRECT_LINK)) {
- addLinkToStructure(directLinks, link);
- removeLinkFromStructure(tunnelLinks, link);
- removeLinkFromStructure(portBroadcastDomainLinks, link);
- dtLinksUpdated = true;
- }
- linksUpdated = true;
- }
-
- public void removeLink(Link link) {
- boolean flag1 = false, flag2 = false;
-
- flag1 = removeLinkFromStructure(directLinks, link);
- flag2 = removeLinkFromStructure(tunnelLinks, link);
-
- linksUpdated = true;
- dtLinksUpdated = flag1 || flag2;
-
- removeLinkFromStructure(portBroadcastDomainLinks, link);
- removeLinkFromStructure(switchPortLinks, link);
-
- NodePortTuple srcNpt =
- new NodePortTuple(link.getSrc(), link.getSrcPort());
- NodePortTuple dstNpt =
- new NodePortTuple(link.getDst(), link.getDstPort());
-
- // Remove switch ports if there are no links through those switch ports
- if (switchPortLinks.get(srcNpt) == null) {
- if (switchPorts.get(srcNpt.getNodeId()) != null)
- switchPorts.get(srcNpt.getNodeId()).remove(srcNpt.getPortId());
- }
- if (switchPortLinks.get(dstNpt) == null) {
- if (switchPorts.get(dstNpt.getNodeId()) != null)
- switchPorts.get(dstNpt.getNodeId()).remove(dstNpt.getPortId());
- }
-
- // Remove the node if no ports are present
- if (switchPorts.get(srcNpt.getNodeId())!=null &&
- switchPorts.get(srcNpt.getNodeId()).isEmpty()) {
- switchPorts.remove(srcNpt.getNodeId());
- }
- if (switchPorts.get(dstNpt.getNodeId())!=null &&
- switchPorts.get(dstNpt.getNodeId()).isEmpty()) {
- switchPorts.remove(dstNpt.getNodeId());
- }
- }
-
- public void removeLink(long srcId, short srcPort,
- long dstId, short dstPort) {
- Link link = new Link(srcId, srcPort, dstId, dstPort);
- removeLink(link);
- }
-
- public void clear() {
- switchPorts.clear();
- switchPortLinks.clear();
- portBroadcastDomainLinks.clear();
- tunnelLinks.clear();
- directLinks.clear();
- appliedUpdates.clear();
- }
-
- /**
- * Clears the current topology. Note that this does NOT
- * send out updates.
- */
- public void clearCurrentTopology() {
- this.clear();
- linksUpdated = true;
- dtLinksUpdated = true;
- createNewInstance();
- lastUpdateTime = new Date();
- }
-
- /**
- * Getters. No Setters.
- */
- public Map<Long, Set<Short>> getSwitchPorts() {
- return switchPorts;
- }
-
- public Map<NodePortTuple, Set<Link>> getSwitchPortLinks() {
- return switchPortLinks;
- }
-
- public Map<NodePortTuple, Set<Link>> getPortBroadcastDomainLinks() {
- return portBroadcastDomainLinks;
- }
-
- public TopologyInstance getCurrentInstance(boolean tunnelEnabled) {
- if (tunnelEnabled)
- return currentInstance;
- else return this.currentInstanceWithoutTunnels;
- }
-
- public TopologyInstance getCurrentInstance() {
- return this.getCurrentInstance(true);
- }
-
- /**
- * Switch methods
- */
- public Set<Short> getPorts(long sw) {
- Set<Short> ports = new HashSet<Short>();
- IOFSwitch iofSwitch = floodlightProvider.getSwitches().get(sw);
- if (iofSwitch == null) return null;
-
- Collection<Short> ofpList = iofSwitch.getEnabledPortNumbers();
- if (ofpList == null) return null;
-
- Set<Short> qPorts = linkDiscovery.getQuarantinedPorts(sw);
- if (qPorts != null)
- ofpList.removeAll(qPorts);
-
- ports.addAll(ofpList);
- return ports;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/web/BlockedPortsResource.java b/src/main/java/net/floodlightcontroller/topology/web/BlockedPortsResource.java
deleted file mode 100644
index dc4ac61..0000000
--- a/src/main/java/net/floodlightcontroller/topology/web/BlockedPortsResource.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package net.floodlightcontroller.topology.web;
-
-import java.util.Set;
-
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.topology.NodePortTuple;
-
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-
-public class BlockedPortsResource extends ServerResource {
- @Get("json")
- public Set<NodePortTuple> retrieve() {
- ITopologyService topology =
- (ITopologyService)getContext().getAttributes().
- get(ITopologyService.class.getCanonicalName());
-
- return topology.getBlockedPorts();
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/web/BroadcastDomainPortsResource.java b/src/main/java/net/floodlightcontroller/topology/web/BroadcastDomainPortsResource.java
deleted file mode 100644
index 61b4338..0000000
--- a/src/main/java/net/floodlightcontroller/topology/web/BroadcastDomainPortsResource.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package net.floodlightcontroller.topology.web;
-
-import java.util.Set;
-
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.topology.NodePortTuple;
-
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-
-public class BroadcastDomainPortsResource extends ServerResource {
- @Get("json")
- public Set<NodePortTuple> retrieve() {
- ITopologyService topology =
- (ITopologyService)getContext().getAttributes().
- get(ITopologyService.class.getCanonicalName());
-
- return topology.getBroadcastDomainPorts();
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/web/EnabledPortsResource.java b/src/main/java/net/floodlightcontroller/topology/web/EnabledPortsResource.java
deleted file mode 100644
index aa75321..0000000
--- a/src/main/java/net/floodlightcontroller/topology/web/EnabledPortsResource.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.floodlightcontroller.topology.web;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.topology.NodePortTuple;
-
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-
-public class EnabledPortsResource extends ServerResource {
- @Get("json")
- public List<NodePortTuple> retrieve() {
- List<NodePortTuple> result = new ArrayList<NodePortTuple>();
-
- IFloodlightProviderService floodlightProvider =
- (IFloodlightProviderService)getContext().getAttributes().
- get(IFloodlightProviderService.class.getCanonicalName());
-
- ITopologyService topology=
- (ITopologyService)getContext().getAttributes().
- get(ITopologyService.class.getCanonicalName());
-
- if (floodlightProvider == null || topology == null)
- return result;
-
- Set<Long> switches = floodlightProvider.getSwitches().keySet();
- if (switches == null) return result;
-
- for(long sw: switches) {
- Set<Short> ports = topology.getPorts(sw);
- if (ports == null) continue;
- for(short p: ports) {
- result.add(new NodePortTuple(sw, p));
- }
- }
- return result;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/web/SwitchClustersResource.java b/src/main/java/net/floodlightcontroller/topology/web/SwitchClustersResource.java
deleted file mode 100644
index f52d27a..0000000
--- a/src/main/java/net/floodlightcontroller/topology/web/SwitchClustersResource.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.topology.web;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.topology.ITopologyService;
-
-import org.openflow.util.HexString;
-import org.restlet.data.Form;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-
-/**
- * Returns a JSON map of <ClusterId, List<SwitchDpids>>
- */
-public class SwitchClustersResource extends ServerResource {
- @Get("json")
- public Map<String, List<String>> retrieve() {
- IFloodlightProviderService floodlightProvider =
- (IFloodlightProviderService)getContext().getAttributes().
- get(IFloodlightProviderService.class.getCanonicalName());
- ITopologyService topology =
- (ITopologyService)getContext().getAttributes().
- get(ITopologyService.class.getCanonicalName());
-
- Form form = getQuery();
- String queryType = form.getFirstValue("type", true);
- boolean openflowDomain = true;
- if (queryType != null && "l2".equals(queryType)) {
- openflowDomain = false;
- }
-
- Map<String, List<String>> switchClusterMap = new HashMap<String, List<String>>();
- for (Entry<Long, IOFSwitch> entry : floodlightProvider.getSwitches().entrySet()) {
- Long clusterDpid =
- (openflowDomain
- ? topology.getOpenflowDomainId(entry.getValue().getId())
- :topology.getL2DomainId(entry.getValue().getId()));
- List<String> switchesInCluster = switchClusterMap.get(HexString.toHexString(clusterDpid));
- if (switchesInCluster != null) {
- switchesInCluster.add(HexString.toHexString(entry.getKey()));
- } else {
- List<String> l = new ArrayList<String>();
- l.add(HexString.toHexString(entry.getKey()));
- switchClusterMap.put(HexString.toHexString(clusterDpid), l);
- }
- }
- return switchClusterMap;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java b/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
deleted file mode 100644
index 363a194..0000000
--- a/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package net.floodlightcontroller.topology.web;
-
-import org.restlet.Context;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-public class TopologyWebRoutable implements RestletRoutable {
- /**
- * Create the Restlet router and bind to the proper resources.
- */
- @Override
- public Router getRestlet(Context context) {
- Router router = new Router(context);
- router.attach("/tunnellinks/json", TunnelLinksResource.class);
- router.attach("/switchclusters/json", SwitchClustersResource.class);
- router.attach("/broadcastdomainports/json", BroadcastDomainPortsResource.class);
- router.attach("/enabledports/json", EnabledPortsResource.class);
- router.attach("/blockedports/json", BlockedPortsResource.class);
- return router;
- }
-
- /**
- * Set the base path for the Topology
- */
- @Override
- public String basePath() {
- return "/wm/floodlight/topology";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/web/TunnelLinksResource.java b/src/main/java/net/floodlightcontroller/topology/web/TunnelLinksResource.java
deleted file mode 100644
index 71c3f12..0000000
--- a/src/main/java/net/floodlightcontroller/topology/web/TunnelLinksResource.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package net.floodlightcontroller.topology.web;
-
-import java.util.Set;
-
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.topology.NodePortTuple;
-
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-
-public class TunnelLinksResource extends ServerResource {
- @Get("json")
- public Set<NodePortTuple> retrieve() {
- ITopologyService topology =
- (ITopologyService)getContext().getAttributes().
- get(ITopologyService.class.getCanonicalName());
-
- return topology.getTunnelPorts();
- }
-}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index 49be7d9..a1da185 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -6,7 +6,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -28,13 +27,9 @@
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.Link;
-import net.floodlightcontroller.topology.ITopologyListener;
-import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.ofcontroller.bgproute.RibUpdate.Operation;
import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
-import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.ofcontroller.proxyarp.IArpRequester;
@@ -78,13 +73,12 @@
import com.google.common.util.concurrent.ThreadFactoryBuilder;
public class BgpRoute implements IFloodlightModule, IBgpRouteService,
- ITopologyListener, IArpRequester,
+ IArpRequester,
IOFSwitchListener, IConfigInfoService {
private final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
private IFloodlightProviderService floodlightProvider;
- private ITopologyService topologyService;
private ILinkDiscoveryService linkDiscoveryService;
private IRestApiService restApi;
private IProxyArpService proxyArp;
@@ -252,7 +246,6 @@
Collection<Class<? extends IFloodlightService>> l
= new ArrayList<Class<? extends IFloodlightService>>();
l.add(IFloodlightProviderService.class);
- l.add(ITopologyService.class);
l.add(IRestApiService.class);
return l;
}
@@ -268,7 +261,6 @@
// Register floodlight provider and REST handler.
floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
- topologyService = context.getServiceImpl(ITopologyService.class);
linkDiscoveryService = context.getServiceImpl(ILinkDiscoveryService.class);
restApi = context.getServiceImpl(IRestApiService.class);
proxyArp = context.getServiceImpl(IProxyArpService.class);
@@ -322,7 +314,6 @@
@Override
public void startUp(FloodlightModuleContext context) {
restApi.addRestletRoutable(new BgpRouteWebRoutable());
- topologyService.addListener(this);
floodlightProvider.addOFSwitchListener(this);
//Retrieve the RIB from BGPd during startup
@@ -1298,6 +1289,10 @@
}
}
+ // The code below should be reimplemented after removal of Floodlight's
+ // ITopologyService API. It should be implemented on top of network graph
+ // notifications. (It was pretty hacky anyway...)
+ /*
@Override
public void topologyChanged() {
if (topologyReady) {
@@ -1325,6 +1320,7 @@
topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
}
}
+ */
@Override
public void addedSwitch(IOFSwitch sw) {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java
index 4b47501..ed4dd7d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java
@@ -20,7 +20,6 @@
import java.io.Serializable;
import java.util.Date;
-import net.floodlightcontroller.devicemanager.internal.Entity;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.util.MACAddress;
@@ -78,14 +77,6 @@
*/
private Date lastSeenTimestamp;
- /**
- * The time between {@link Entity#activeSince} and
- * {@link Entity#lastSeenTimestamp} is a period of activity for this
- * entity where it was observed repeatedly. If, when the entity is
- * observed, the is longer ago than the activity timeout,
- * {@link Entity#lastSeenTimestamp} and {@link Entity#activeSince} will
- * be set to the current time.
- */
private Date activeSince;
private int hashCode = 0;
@@ -156,12 +147,7 @@
return lastSeenTimestamp;
}
- /**
- * Set the last seen timestamp and also update {@link Entity#activeSince}
- * if appropriate
- * @param lastSeenTimestamp the new last seen timestamp
- * @see {@link Entity#activeSince}
- */
+
public void setLastSeenTimestamp(Date lastSeenTimestamp) {
if (activeSince == null ||
(activeSince.getTime() + ACTIVITY_TIMEOUT) <
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/OldNetworkGraphPublisher.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/OldNetworkGraphPublisher.java
index f664dfd..7c05467 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/OldNetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/OldNetworkGraphPublisher.java
@@ -2,10 +2,7 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
-import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -16,30 +13,20 @@
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.core.util.SingletonTask;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceListener;
-import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.datagrid.IDatagridService;
import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
-import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
-import net.onrc.onos.ofcontroller.util.PerformanceMonitor;
+import net.onrc.onos.ofcontroller.linkdiscovery.Link;
import net.onrc.onos.registry.controller.IControllerRegistryService;
import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
-import net.onrc.onos.registry.controller.RegistryException;
import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.net.InetAddresses;
-
-public class OldNetworkGraphPublisher implements IDeviceListener,
+public class OldNetworkGraphPublisher implements
IOFSwitchListener,
IOFSwitchPortListener,
ILinkDiscoveryListener,
@@ -391,41 +378,6 @@
}
@Override
- public void deviceAdded(IDevice device) {
- log.debug("{}:deviceAdded(): Adding device {}",this.getClass(),device.getMACAddressString());
- /*
- devStore.addDevice(device);
- for (int intIpv4Address : device.getIPv4Addresses()) {
- datagridService.sendArpReplyNotification(new ArpReplyNotification(
- InetAddresses.fromInteger(intIpv4Address),
- MACAddress.valueOf(device.getMACAddress())));
- }
- */
- }
-
- @Override
- public void deviceRemoved(IDevice device) {
- // TODO Auto-generated method stub
- // devStore.removeDevice(device);
- }
-
- @Override
- public void deviceMoved(IDevice device) {
- // devStore.changeDeviceAttachments(device);
- }
-
- @Override
- public void deviceIPV4AddrChanged(IDevice device) {
- // devStore.changeDeviceIPv4Address(device);
- }
-
- @Override
- public void deviceVlanChanged(IDevice device) {
- // TODO Auto-generated method stub
- }
-
-
- @Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
return null;
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryService.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryService.java
index 99438ab..2b45200 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryService.java
@@ -21,8 +21,6 @@
import java.util.Set;
import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.routing.Link;
-import net.floodlightcontroller.topology.NodePortTuple;
public interface ILinkDiscoveryService extends IFloodlightService {
diff --git a/src/main/java/net/floodlightcontroller/routing/Link.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/Link.java
similarity index 98%
rename from src/main/java/net/floodlightcontroller/routing/Link.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/Link.java
index 7958596..38fc3d9 100755
--- a/src/main/java/net/floodlightcontroller/routing/Link.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/Link.java
@@ -15,7 +15,7 @@
* under the License.
**/
-package net.floodlightcontroller.routing;
+package net.onrc.onos.ofcontroller.linkdiscovery;
import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
import net.floodlightcontroller.core.web.serializers.UShortSerializer;
diff --git a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/NodePortTuple.java
similarity index 97%
rename from src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/NodePortTuple.java
index 4983529..646386c 100644
--- a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/NodePortTuple.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.topology;
+package net.onrc.onos.ofcontroller.linkdiscovery;
import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
import net.floodlightcontroller.core.web.serializers.UShortSerializer;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index 3bb2878..a035867 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -58,9 +58,7 @@
import net.floodlightcontroller.packet.LLDP;
import net.floodlightcontroller.packet.LLDPTLV;
import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.util.EventHistory;
import net.floodlightcontroller.util.EventHistory.EvAction;
import net.onrc.onos.ofcontroller.core.IOnosRemoteSwitch;
@@ -69,7 +67,9 @@
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.UpdateOperation;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.Link;
import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+import net.onrc.onos.ofcontroller.linkdiscovery.NodePortTuple;
import net.onrc.onos.ofcontroller.linkdiscovery.web.LinkDiscoveryWebRoutable;
import net.onrc.onos.registry.controller.IControllerRegistryService;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkWithType.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkWithType.java
index 3e5a5e7..6fa430e 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkWithType.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkWithType.java
@@ -9,7 +9,7 @@
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.openflow.util.HexString;
-import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.linkdiscovery.Link;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LinkType;
/**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinksResource.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinksResource.java
index 3c97e6a..ce6b2fa 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinksResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinksResource.java
@@ -6,8 +6,8 @@
import java.util.Map.Entry;
import java.util.Set;
-import net.floodlightcontroller.routing.Link;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.Link;
import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
import org.restlet.resource.Get;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 1593369..9e2ae4c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -1,12 +1,10 @@
package net.onrc.onos.ofcontroller.proxyarp;
-import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -25,14 +23,11 @@
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.datagrid.IDatagridService;
import net.onrc.onos.ofcontroller.bgproute.Interface;
import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
-import net.onrc.onos.ofcontroller.util.Dpid;
-import net.onrc.onos.ofcontroller.util.Port;
import net.onrc.onos.ofcontroller.util.SwitchPort;
import org.openflow.protocol.OFMessage;
@@ -49,7 +44,6 @@
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
-import com.google.common.net.InetAddresses;
public class ProxyArpManager implements IProxyArpService, IOFMessageListener,
IPacketOutEventHandler, IArpReplyEventHandler,
@@ -61,7 +55,6 @@
private static final int ARP_REQUEST_TIMEOUT = 2000; //ms
private IFloodlightProviderService floodlightProvider;
- private ITopologyService topology;
private IDatagridService datagrid;
private IConfigInfoService configService;
private IRestApiService restApi;
@@ -146,7 +139,6 @@
Collection<Class<? extends IFloodlightService>> dependencies
= new ArrayList<Class<? extends IFloodlightService>>();
dependencies.add(IFloodlightProviderService.class);
- dependencies.add(ITopologyService.class);
dependencies.add(IRestApiService.class);
dependencies.add(IDatagridService.class);
dependencies.add(IConfigInfoService.class);
@@ -158,7 +150,6 @@
public void init(FloodlightModuleContext context){
this.floodlightProvider =
context.getServiceImpl(IFloodlightProviderService.class);
- this.topology = context.getServiceImpl(ITopologyService.class);
this.datagrid = context.getServiceImpl(IDatagridService.class);
this.configService = context.getServiceImpl(IConfigInfoService.class);
this.restApi = context.getServiceImpl(IRestApiService.class);
@@ -556,58 +547,6 @@
datagrid.sendArpReplyNotification(new ArpReplyNotification(targetAddress, mac));
}
- // This remains from the older single-instance ARP code. It used Floodlight
- // APIs to find the edge of the network, but only worked on a single instance.
- // We now do this using ONOS network graph APIs.
- @Deprecated
- private void broadcastArpRequestOutEdge(byte[] arpRequest, long inSwitch, short inPort) {
- for (IOFSwitch sw : floodlightProvider.getSwitches().values()){
- Collection<Short> enabledPorts = sw.getEnabledPortNumbers();
- Set<Short> linkPorts = topology.getPortsWithLinks(sw.getId());
-
- if (linkPorts == null){
- //I think this means the switch doesn't have any links.
- //continue;
- linkPorts = new HashSet<Short>();
- }
-
-
- OFPacketOut po = new OFPacketOut();
- po.setInPort(OFPort.OFPP_NONE)
- .setBufferId(-1)
- .setPacketData(arpRequest);
-
- List<OFAction> actions = new ArrayList<OFAction>();
-
- for (short portNum : enabledPorts){
- if (linkPorts.contains(portNum) ||
- (sw.getId() == inSwitch && portNum == inPort)){
- //If this port isn't an edge port or is the ingress port
- //for the ARP, don't broadcast out it
- continue;
- }
-
- actions.add(new OFActionOutput(portNum));
- }
-
- po.setActions(actions);
- short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
- po.setActionsLength(actionsLength);
- po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength
- + arpRequest.length);
-
- List<OFMessage> msgList = new ArrayList<OFMessage>();
- msgList.add(po);
-
- try {
- sw.write(msgList, null);
- sw.flush();
- } catch (IOException e) {
- log.error("Failure writing packet out to switch", e);
- }
- }
- }
-
private void broadcastArpRequestOutMyEdge(byte[] arpRequest,
long inSwitch, short inPort) {
List<SwitchPort> switchPorts = new ArrayList<SwitchPort>();
diff --git a/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java b/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java
index 89a3591..beb6d4f 100644
--- a/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java
+++ b/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java
@@ -6,9 +6,6 @@
import net.floodlightcontroller.core.test.MockFloodlightProvider;
import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
-import net.floodlightcontroller.topology.TopologyManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -19,25 +16,16 @@
// List of default modules to use unless specified otherwise
public static final Class<? extends IFloodlightModule> DEFAULT_FLOODLIGHT_PRPOVIDER =
MockFloodlightProvider.class;
- public static final Class<? extends IFloodlightModule> DEFAULT_TOPOLOGY_PROVIDER =
- TopologyManager.class;
- public static final Class<? extends IFloodlightModule> DEFAULT_DEVICE_SERVICE =
- MockDeviceManager.class;
public static final Class<? extends IFloodlightModule> DEFAULT_THREADPOOL =
MockThreadPoolService.class;
- public static final Class<? extends IFloodlightModule> DEFAULT_ENTITY_CLASSIFIER =
- DefaultEntityClassifier.class;
protected static final Collection<Class<? extends IFloodlightModule>> DEFAULT_MODULE_LIST;
static {
DEFAULT_MODULE_LIST = new ArrayList<Class<? extends IFloodlightModule>>();
- DEFAULT_MODULE_LIST.add(DEFAULT_DEVICE_SERVICE);
DEFAULT_MODULE_LIST.add(DEFAULT_FLOODLIGHT_PRPOVIDER);
- DEFAULT_MODULE_LIST.add(DEFAULT_TOPOLOGY_PROVIDER);
DEFAULT_MODULE_LIST.add(DEFAULT_THREADPOOL);
- DEFAULT_MODULE_LIST.add(DEFAULT_ENTITY_CLASSIFIER);
}
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
deleted file mode 100644
index b37efe3..0000000
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ /dev/null
@@ -1,1760 +0,0 @@
-/**
- * Copyright 2011, Big Switch Networks, Inc.
- * Originally created by David Erickson, Stanford 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- **/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-
-import static org.easymock.EasyMock.anyLong;
-import static org.easymock.EasyMock.anyShort;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createStrictMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.isA;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertArrayEquals;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-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;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.IEntityClassifierService;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.devicemanager.SwitchPort.ErrorStatus;
-import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl.ClassState;
-import net.floodlightcontroller.devicemanager.test.MockEntityClassifier;
-import net.floodlightcontroller.devicemanager.test.MockEntityClassifierMac;
-import net.floodlightcontroller.devicemanager.test.MockFlexEntityClassifier;
-import net.floodlightcontroller.packet.ARP;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.ITopologyService;
-
-import org.easymock.EasyMock;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFType;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Ignore //TODO broken 11/19/13, should fix
-public class DeviceManagerImplTest extends FloodlightTestCase {
-
- protected final static Logger logger =
- LoggerFactory.getLogger(DeviceManagerImplTest.class);
-
- protected OFPacketIn packetIn_1, packetIn_2, packetIn_3;
- protected IPacket testARPReplyPacket_1, testARPReplyPacket_2,
- testARPReplyPacket_3;
- protected IPacket testARPReqPacket_1, testARPReqPacket_2;
- protected byte[] testARPReplyPacket_1_Srld, testARPReplyPacket_2_Srld;
- private byte[] testARPReplyPacket_3_Serialized;
- MockFloodlightProvider mockFloodlightProvider;
- DeviceManagerImpl deviceManager;
-
- private IOFSwitch makeSwitchMock(long id) {
- IOFSwitch mockSwitch = createMock(IOFSwitch.class);
- expect(mockSwitch.getId()).andReturn(id).anyTimes();
- expect(mockSwitch.getStringId()).
- andReturn(HexString.toHexString(id, 6)).anyTimes();
- expect(mockSwitch.getPort(anyShort())).
- andReturn(new OFPhysicalPort()).anyTimes();
- expect(mockSwitch.portEnabled(isA(OFPhysicalPort.class))).
- andReturn(true).anyTimes();
- return mockSwitch;
- }
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- FloodlightModuleContext fmc = new FloodlightModuleContext();
- RestApiServer restApi = new RestApiServer();
- MockThreadPoolService tp = new MockThreadPoolService();
- ITopologyService topology = createMock(ITopologyService.class);
- fmc.addService(IThreadPoolService.class, tp);
- mockFloodlightProvider = getMockFloodlightProvider();
- deviceManager = new DeviceManagerImpl();
-
- DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
- fmc.addService(IDeviceService.class, deviceManager);
- //storageSource = new MemoryStorageSource();
- //fmc.addService(IStorageSourceService.class, storageSource);
- fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider);
- fmc.addService(IRestApiService.class, restApi);
-
- fmc.addService(IEntityClassifierService.class, entityClassifier);
- fmc.addService(ITopologyService.class, topology);
- tp.init(fmc);
- restApi.init(fmc);
- //storageSource.init(fmc);
- deviceManager.init(fmc);
-
- entityClassifier.init(fmc);
- //storageSource.startUp(fmc);
- deviceManager.startUp(fmc);
-
- tp.startUp(fmc);
- entityClassifier.startUp(fmc);
-
- reset(topology);
- topology.addListener(deviceManager);
- expectLastCall().anyTimes();
- replay(topology);
-
- IOFSwitch mockSwitch1 = makeSwitchMock(1L);
- IOFSwitch mockSwitch10 = makeSwitchMock(10L);
- IOFSwitch mockSwitch5 = makeSwitchMock(5L);
- IOFSwitch mockSwitch50 = makeSwitchMock(50L);
- Map<Long, IOFSwitch> switches = new HashMap<Long,IOFSwitch>();
- switches.put(1L, mockSwitch1);
- switches.put(10L, mockSwitch10);
- switches.put(5L, mockSwitch5);
- switches.put(50L, mockSwitch50);
- mockFloodlightProvider.setSwitches(switches);
-
- replay(mockSwitch1, mockSwitch5, mockSwitch10, mockSwitch50);
-
- // Build our test packet
- this.testARPReplyPacket_1 = new Ethernet()
- .setSourceMACAddress("00:44:33:22:11:01")
- .setDestinationMACAddress("00:11:22:33:44:55")
- .setEtherType(Ethernet.TYPE_ARP)
- .setVlanID((short)5)
- .setPayload(
- new ARP()
- .setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(ARP.PROTO_TYPE_IP)
- .setHardwareAddressLength((byte) 6)
- .setProtocolAddressLength((byte) 4)
- .setOpCode(ARP.OP_REPLY)
- .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
- .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
- .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
- .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
- this.testARPReplyPacket_1_Srld = testARPReplyPacket_1.serialize();
-
- // Another test packet with a different source IP
- this.testARPReplyPacket_2 = new Ethernet()
- .setSourceMACAddress("00:44:33:22:11:01")
- .setDestinationMACAddress("00:11:22:33:44:55")
- .setEtherType(Ethernet.TYPE_ARP)
- .setPayload(
- new ARP()
- .setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(ARP.PROTO_TYPE_IP)
- .setHardwareAddressLength((byte) 6)
- .setProtocolAddressLength((byte) 4)
- .setOpCode(ARP.OP_REPLY)
- .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
- .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
- .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
- .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
- this.testARPReplyPacket_2_Srld = testARPReplyPacket_2.serialize();
-
- this.testARPReplyPacket_3 = new Ethernet()
- .setSourceMACAddress("00:44:33:22:11:01")
- .setDestinationMACAddress("00:11:22:33:44:55")
- .setEtherType(Ethernet.TYPE_ARP)
- .setPayload(
- new ARP()
- .setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(ARP.PROTO_TYPE_IP)
- .setHardwareAddressLength((byte) 6)
- .setProtocolAddressLength((byte) 4)
- .setOpCode(ARP.OP_REPLY)
- .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
- .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.3"))
- .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
- .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
- this.testARPReplyPacket_3_Serialized = testARPReplyPacket_3.serialize();
-
- // Build the PacketIn
- this.packetIn_1 = ((OFPacketIn) mockFloodlightProvider.
- getOFMessageFactory().getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(this.testARPReplyPacket_1_Srld)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) this.testARPReplyPacket_1_Srld.length);
-
- // Build the PacketIn
- this.packetIn_2 = ((OFPacketIn) mockFloodlightProvider.
- getOFMessageFactory().getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(this.testARPReplyPacket_2_Srld)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) this.testARPReplyPacket_2_Srld.length);
-
- // Build the PacketIn
- this.packetIn_3 = ((OFPacketIn) mockFloodlightProvider.
- getOFMessageFactory().getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(this.testARPReplyPacket_3_Serialized)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) this.testARPReplyPacket_3_Serialized.length);
- }
-
-
-
-
-
- @Test
- public void testLastSeen() throws Exception {
- Calendar c = Calendar.getInstance();
- Date d1 = c.getTime();
- Entity entity1 = new Entity(1L, null, null, null, null, d1);
- c.add(Calendar.SECOND, 1);
- Entity entity2 = new Entity(1L, null, 1, null, null, c.getTime());
-
- IDevice d = deviceManager.learnDeviceByEntity(entity2);
- assertEquals(c.getTime(), d.getLastSeen());
- d = deviceManager.learnDeviceByEntity(entity1);
- assertEquals(c.getTime(), d.getLastSeen());
-
- deviceManager.startUp(null);
- d = deviceManager.learnDeviceByEntity(entity1);
- assertEquals(d1, d.getLastSeen());
- d = deviceManager.learnDeviceByEntity(entity2);
- assertEquals(c.getTime(), d.getLastSeen());
- }
-
- @Test
- public void testEntityLearning() throws Exception {
- IDeviceListener mockListener =
- createStrictMock(IDeviceListener.class);
-
- deviceManager.addListener(mockListener);
- deviceManager.entityClassifier= new MockEntityClassifier();
- deviceManager.startUp(null);
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- expect(mockTopology.getL2DomainId(anyLong())).
- andReturn(1L).anyTimes();
- expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
- andReturn(false).anyTimes();
-
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).andReturn(true).anyTimes();
- expect(mockTopology.isConsistent(10L, (short)1, 10L, (short)1)).
- andReturn(true).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)1)).
- andReturn(true).anyTimes();
- expect(mockTopology.isConsistent(50L, (short)3, 50L, (short)3)).
- andReturn(true).anyTimes();
-
- Date topologyUpdateTime = new Date();
- expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
- anyTimes();
-
- deviceManager.topology = mockTopology;
-
- Entity entity1 = new Entity(1L, null, null, 1L, 1, new Date());
- Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date());
- Entity entity3 = new Entity(1L, null, 1, 10L, 1, new Date());
- Entity entity4 = new Entity(1L, null, 1, 1L, 1, new Date());
- Entity entity5 = new Entity(2L, (short)4, 1, 5L, 2, new Date());
- Entity entity6 = new Entity(2L, (short)4, 1, 50L, 3, new Date());
- Entity entity7 = new Entity(2L, (short)4, 2, 50L, 3, new Date());
-
- mockListener.deviceAdded(isA(IDevice.class));
- replay(mockListener, mockTopology);
-
- Device d1 = deviceManager.learnDeviceByEntity(entity1);
- assertSame(d1, deviceManager.learnDeviceByEntity(entity1));
- assertSame(d1, deviceManager.findDeviceByEntity(entity1));
- assertEquals(DefaultEntityClassifier.entityClass ,
- d1.entityClass);
- assertArrayEquals(new Short[] { -1 }, d1.getVlanId());
- assertArrayEquals(new Integer[] { }, d1.getIPv4Addresses());
-
- assertEquals(1, deviceManager.getAllDevices().size());
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceAdded(isA(IDevice.class));
- replay(mockListener);
-
- Device d2 = deviceManager.learnDeviceByEntity(entity2);
- assertFalse(d1.equals(d2));
- assertNotSame(d1, d2);
- assertNotSame(d1.getDeviceKey(), d2.getDeviceKey());
- assertEquals(MockEntityClassifier.testEC, d2.entityClass);
- assertArrayEquals(new Short[] { -1 }, d2.getVlanId());
- assertArrayEquals(new Integer[] { }, d2.getIPv4Addresses());
-
- assertEquals(2, deviceManager.getAllDevices().size());
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
- replay(mockListener);
-
- Device d3 = deviceManager.learnDeviceByEntity(entity3);
- assertNotSame(d2, d3);
- assertEquals(d2.getDeviceKey(), d3.getDeviceKey());
- assertEquals(MockEntityClassifier.testEC, d3.entityClass);
- assertArrayEquals(new Integer[] { 1 },
- d3.getIPv4Addresses());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
- d3.getAttachmentPoints());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
- d3.getAttachmentPoints(true));
- assertArrayEquals(new Short[] { -1 },
- d3.getVlanId());
-
- assertEquals(2, deviceManager.getAllDevices().size());
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
- replay(mockListener);
-
- Device d4 = deviceManager.learnDeviceByEntity(entity4);
- assertNotSame(d1, d4);
- assertEquals(d1.getDeviceKey(), d4.getDeviceKey());
- assertEquals(DefaultEntityClassifier.entityClass, d4.entityClass);
- assertArrayEquals(new Integer[] { 1 },
- d4.getIPv4Addresses());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
- d4.getAttachmentPoints());
- assertArrayEquals(new Short[] { -1 },
- d4.getVlanId());
-
- assertEquals(2, deviceManager.getAllDevices().size());
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceAdded((isA(IDevice.class)));
- replay(mockListener);
-
- Device d5 = deviceManager.learnDeviceByEntity(entity5);
- assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 2) },
- d5.getAttachmentPoints());
- assertArrayEquals(new Short[] { (short) 4 },
- d5.getVlanId());
- assertEquals(2L, d5.getMACAddress());
- assertEquals("00:00:00:00:00:02", d5.getMACAddressString());
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceAdded(isA(IDevice.class));
- replay(mockListener);
-
- Device d6 = deviceManager.learnDeviceByEntity(entity6);
- assertArrayEquals(new SwitchPort[] { new SwitchPort(50L, 3) },
- d6.getAttachmentPoints());
- assertArrayEquals(new Short[] { (short) 4 },
- d6.getVlanId());
-
- assertEquals(4, deviceManager.getAllDevices().size());
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
- replay(mockListener);
-
- Device d7 = deviceManager.learnDeviceByEntity(entity7);
- assertNotSame(d6, d7);
- assertEquals(d6.getDeviceKey(), d7.getDeviceKey());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(50L, 3) },
- d7.getAttachmentPoints());
- assertArrayEquals(new Short[] { (short) 4 },
- d7.getVlanId());
-
- assertEquals(4, deviceManager.getAllDevices().size());
- verify(mockListener);
-
-
- reset(mockListener);
- replay(mockListener);
-
- reset(deviceManager.topology);
- deviceManager.topology.addListener(deviceManager);
- expectLastCall().times(1);
- replay(deviceManager.topology);
-
- deviceManager.entityClassifier = new MockEntityClassifierMac();
- deviceManager.startUp(null);
- Entity entityNoClass = new Entity(5L, (short)1, 5, -1L, 1, new Date());
- assertEquals(null, deviceManager.learnDeviceByEntity(entityNoClass));
-
- verify(mockListener);
- }
-
-
- @Test
- public void testAttachmentPointLearning() throws Exception {
- IDeviceListener mockListener =
- createStrictMock(IDeviceListener.class);
-
- deviceManager.addListener(mockListener);
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- expect(mockTopology.getL2DomainId(1L)).
- andReturn(1L).anyTimes();
- expect(mockTopology.getL2DomainId(5L)).
- andReturn(1L).anyTimes();
- expect(mockTopology.getL2DomainId(10L)).
- andReturn(10L).anyTimes();
- expect(mockTopology.getL2DomainId(50L)).
- andReturn(10L).anyTimes();
- expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
- andReturn(false).anyTimes();
- expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
- anyLong(), anyShort())).andReturn(false).anyTimes();
-
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).andReturn(true).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(5L, (short)1, 10L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(10L, (short)1, 50L, (short)1)).
- andReturn(false).anyTimes();
-
- Date topologyUpdateTime = new Date();
- expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
- anyTimes();
-
- replay(mockTopology);
-
- deviceManager.topology = mockTopology;
-
- Calendar c = Calendar.getInstance();
- Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
- Entity entity0 = new Entity(1L, null, null, null, null, c.getTime());
- c.add(Calendar.SECOND, 1);
- Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
- c.add(Calendar.SECOND, 1);
- Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
- c.add(Calendar.SECOND, 1);
- Entity entity4 = new Entity(1L, null, null, 50L, 1, c.getTime());
-
- IDevice d;
- SwitchPort[] aps;
- Integer[] ips;
-
- mockListener.deviceAdded(isA(IDevice.class));
- replay(mockListener);
-
- deviceManager.learnDeviceByEntity(entity1);
- d = deviceManager.learnDeviceByEntity(entity0);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
- ips = d.getIPv4Addresses();
- assertArrayEquals(new Integer[] { 1 }, ips);
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceMoved((isA(IDevice.class)));
- replay(mockListener);
-
- d = deviceManager.learnDeviceByEntity(entity2);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
-
- assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
- ips = d.getIPv4Addresses();
- assertArrayEquals(new Integer[] { 1 }, ips);
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceMoved((isA(IDevice.class)));
- replay(mockListener);
-
- d = deviceManager.learnDeviceByEntity(entity3);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] {new SwitchPort(5L, 1), new SwitchPort(10L, 1)}, aps);
- ips = d.getIPv4Addresses();
- assertArrayEquals(new Integer[] { 1 }, ips);
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceMoved((isA(IDevice.class)));
- replay(mockListener);
-
- d = deviceManager.learnDeviceByEntity(entity4);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1),
- new SwitchPort(50L, 1) }, aps);
- ips = d.getIPv4Addresses();
- assertArrayEquals(new Integer[] { 1 }, ips);
- verify(mockListener);
- }
-
- @Test
- public void testAttachmentPointSuppression() throws Exception {
- IDeviceListener mockListener =
- createStrictMock(IDeviceListener.class);
-
- deviceManager.addListener(mockListener);
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- expect(mockTopology.getL2DomainId(1L)).
- andReturn(1L).anyTimes();
- expect(mockTopology.getL2DomainId(5L)).
- andReturn(1L).anyTimes();
- expect(mockTopology.getL2DomainId(10L)).
- andReturn(10L).anyTimes();
- expect(mockTopology.getL2DomainId(50L)).
- andReturn(10L).anyTimes();
- expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
- andReturn(false).anyTimes();
- expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
- anyLong(), anyShort())).andReturn(false).anyTimes();
-
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).andReturn(true).anyTimes();
- expect(mockTopology.isConsistent(5L, (short)1, 50L, (short)1)).
- andReturn(false).anyTimes();
-
- Date topologyUpdateTime = new Date();
- expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
- anyTimes();
-
- replay(mockTopology);
-
- deviceManager.topology = mockTopology;
- // suppress (1L, 1) and (10L, 1)
- deviceManager.addSuppressAPs(1L, (short)1);
- deviceManager.addSuppressAPs(10L, (short)1);
-
- Calendar c = Calendar.getInstance();
- Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
- Entity entity0 = new Entity(1L, null, null, null, null, c.getTime());
- c.add(Calendar.SECOND, 1);
- Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
- c.add(Calendar.SECOND, 1);
- Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
- c.add(Calendar.SECOND, 1);
- Entity entity4 = new Entity(1L, null, null, 50L, 1, c.getTime());
-
- IDevice d;
- SwitchPort[] aps;
- Integer[] ips;
-
- mockListener.deviceAdded(isA(IDevice.class));
- replay(mockListener);
-
- deviceManager.learnDeviceByEntity(entity1);
- d = deviceManager.learnDeviceByEntity(entity0);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertEquals(aps.length, 0);
- ips = d.getIPv4Addresses();
- assertArrayEquals(new Integer[] { 1 }, ips);
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceMoved((isA(IDevice.class)));
- replay(mockListener);
-
- d = deviceManager.learnDeviceByEntity(entity2);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
- ips = d.getIPv4Addresses();
- assertArrayEquals(new Integer[] { 1 }, ips);
- verify(mockListener);
-
- reset(mockListener);
- mockListener.deviceMoved((isA(IDevice.class)));
- replay(mockListener);
-
- d = deviceManager.learnDeviceByEntity(entity3);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
- ips = d.getIPv4Addresses();
- assertArrayEquals(new Integer[] { 1 }, ips);
- //verify(mockListener); // There is no device movement here; no not needed.
-
- reset(mockListener);
- mockListener.deviceMoved((isA(IDevice.class)));
- replay(mockListener);
-
- d = deviceManager.learnDeviceByEntity(entity4);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1),
- new SwitchPort(50L, 1) }, aps);
- ips = d.getIPv4Addresses();
- assertArrayEquals(new Integer[] { 1 }, ips);
- verify(mockListener);
- }
-
- @Test
- public void testBDAttachmentPointLearning() throws Exception {
- ITopologyService mockTopology = createMock(ITopologyService.class);
- expect(mockTopology.getL2DomainId(anyLong())).
- andReturn(1L).anyTimes();
- expect(mockTopology.isAttachmentPointPort(anyLong(), anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isBroadcastDomainPort(1L, (short)2)).
- andReturn(true).anyTimes();
- expect(mockTopology.isInSameBroadcastDomain(1L, (short)1,
- 1L, (short)2)).andReturn(true).anyTimes();
- expect(mockTopology.isInSameBroadcastDomain(1L, (short)2,
- 1L, (short)1)).andReturn(true).anyTimes();
- expect(mockTopology.isConsistent(anyLong(), anyShort(), anyLong(), anyShort())).andReturn(false).anyTimes();
-
- Date topologyUpdateTime = new Date();
- expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
- anyTimes();
-
- replay(mockTopology);
-
- deviceManager.topology = mockTopology;
-
- Calendar c = Calendar.getInstance();
- Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
- c.add(Calendar.MILLISECOND,
- (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT/ 2);
- Entity entity2 = new Entity(1L, null, null, 1L, 2, c.getTime());
- c.add(Calendar.MILLISECOND,
- (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT / 2 + 1);
- Entity entity3 = new Entity(1L, null, null, 1L, 2, c.getTime());
-
- IDevice d;
- SwitchPort[] aps;
-
- d = deviceManager.learnDeviceByEntity(entity1);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-
- // this timestamp is too soon; don't switch
- d = deviceManager.learnDeviceByEntity(entity2);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-
- // it should switch when we learn with a timestamp after the
- // timeout
- d = deviceManager.learnDeviceByEntity(entity3);
- assertEquals(1, deviceManager.getAllDevices().size());
- aps = d.getAttachmentPoints();
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2) }, aps);
- }
-
-
- @Test
- public void testPacketIn() throws Exception {
- byte[] dataLayerSource =
- ((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress();
-
- // Mock up our expected behavior
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
- expect(mockTopology.isAttachmentPointPort(EasyMock.anyLong(),
- EasyMock.anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.isConsistent(EasyMock.anyLong(),
- EasyMock.anyShort(),
- EasyMock.anyLong(),
- EasyMock.anyShort())).andReturn(false).
- anyTimes();
- expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
- replay(mockTopology);
-
- Date currentDate = new Date();
-
- // build our expected Device
- Integer ipaddr = IPv4.toIPv4Address("192.168.1.1");
- Device device =
- new Device(deviceManager,
- new Long(deviceManager.deviceKeyCounter),
- new Entity(Ethernet.toLong(dataLayerSource),
- (short)5,
- ipaddr,
- 1L,
- 1,
- currentDate),
- DefaultEntityClassifier.entityClass);
-
-
-
-
- // Get the listener and trigger the packet in
- IOFSwitch switch1 = mockFloodlightProvider.getSwitches().get(1L);
- mockFloodlightProvider.dispatchMessage(switch1, this.packetIn_1);
-
- // Verify the replay matched our expectations
- // verify(mockTopology);
-
- // Verify the device
- Device rdevice = (Device)
- deviceManager.findDevice(Ethernet.toLong(dataLayerSource),
- (short)5, null, null, null);
-
- assertEquals(device, rdevice);
- assertEquals(new Short((short)5), rdevice.getVlanId()[0]);
-
- Device result = null;
- Iterator<? extends IDevice> dstiter =
- deviceManager.queryClassDevices(device, null, null, ipaddr,
- null, null);
- if (dstiter.hasNext()) {
- result = (Device)dstiter.next();
- }
-
- assertEquals(device, result);
-
- device =
- new Device(device,
- new Entity(Ethernet.toLong(dataLayerSource),
- (short)5,
- ipaddr,
- 5L,
- 2,
- currentDate));
-
- reset(mockTopology);
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).
- anyTimes();
- expect(mockTopology.isConsistent(EasyMock.anyLong(),
- EasyMock.anyShort(),
- EasyMock.anyLong(),
- EasyMock.anyShort())).andReturn(false).
- anyTimes();
- expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
- EasyMock.anyShort()))
- .andReturn(false)
- .anyTimes();
- expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes();
- expect(mockTopology.getL2DomainId(5L)).andReturn(1L).anyTimes();
- expect(mockTopology.isInSameBroadcastDomain(1L, (short)1, 5L, (short)2)).
- andReturn(false).anyTimes();
-
- // Start recording the replay on the mocks
- replay(mockTopology);
- // Get the listener and trigger the packet in
- IOFSwitch switch5 = mockFloodlightProvider.getSwitches().get(5L);
- mockFloodlightProvider.
- dispatchMessage(switch5, this.packetIn_1.setInPort((short)2));
-
- // Verify the replay matched our expectations
- verify(mockTopology);
-
- // Verify the device
- rdevice = (Device)
- deviceManager.findDevice(Ethernet.toLong(dataLayerSource),
- (short)5, null, null, null);
- assertEquals(device, rdevice);
- }
-
-
- /**
- * Note: Entity expiration does not result in device moved notification.
- * @throws Exception
- */
- public void doTestEntityExpiration() throws Exception {
- IDeviceListener mockListener =
- createStrictMock(IDeviceListener.class);
- mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).anyTimes();
-
- expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).andReturn(false).anyTimes();
- expect(mockTopology.isBroadcastDomainPort(5L, (short)1)).andReturn(false).anyTimes();
- expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes();
- expect(mockTopology.getL2DomainId(5L)).andReturn(5L).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
- andReturn(false).anyTimes();
-
- Date topologyUpdateTime = new Date();
- expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
- anyTimes();
-
- replay(mockTopology);
- deviceManager.topology = mockTopology;
-
- Calendar c = Calendar.getInstance();
- Entity entity1 = new Entity(1L, null, 2, 1L, 1, c.getTime());
- c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1);
- Entity entity2 = new Entity(1L, null, 1, 5L, 1, c.getTime());
-
- deviceManager.learnDeviceByEntity(entity1);
- IDevice d = deviceManager.learnDeviceByEntity(entity2);
- assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 1)},
- d.getAttachmentPoints());
- Iterator<? extends IDevice> diter =
- deviceManager.queryClassDevices(d, null, null, 1, null, null);
- assertTrue(diter.hasNext());
- assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
- diter = deviceManager.queryClassDevices(d, null, null, 2, null, null);
- assertTrue(diter.hasNext());
- assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
-
-
- deviceManager.addListener(mockListener);
- replay(mockListener);
- deviceManager.entityCleanupTask.reschedule(0, null);
-
- d = deviceManager.getDevice(d.getDeviceKey());
- assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses());
-
- // Attachment points are not removed, previous ones are still valid.
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 1) },
- d.getAttachmentPoints());
- diter = deviceManager.queryClassDevices(d, null, null, 2, null, null);
- assertTrue(diter.hasNext());
- assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
- diter = deviceManager.queryClassDevices(d, null, null, 1, null, null);
- assertFalse(diter.hasNext());
-
- d = deviceManager.findDevice(1L, null, null, null, null);
- assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses());
-
- // Attachment points are not removed, previous ones are still valid.
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 1) },
- d.getAttachmentPoints());
-
- verify(mockListener);
- }
-
- public void doTestDeviceExpiration() throws Exception {
- IDeviceListener mockListener =
- createStrictMock(IDeviceListener.class);
- mockListener.deviceRemoved(isA(IDevice.class));
-
- Calendar c = Calendar.getInstance();
- c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1);
- Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
- Entity entity2 = new Entity(1L, null, 2, 5L, 1, c.getTime());
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
-
- expect(mockTopology.isAttachmentPointPort(EasyMock.anyLong(),
- EasyMock.anyShort())).
- andReturn(true).
- anyTimes();
- expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes();
- expect(mockTopology.getL2DomainId(5L)).andReturn(1L).anyTimes();
- expect(mockTopology.isConsistent(EasyMock.anyLong(),
- EasyMock.anyShort(),
- EasyMock.anyLong(),
- EasyMock.anyShort())).andReturn(false).
- anyTimes();
- expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
- EasyMock.anyShort())).
- andReturn(false).anyTimes();
- replay(mockTopology);
-
- IDevice d = deviceManager.learnDeviceByEntity(entity2);
- d = deviceManager.learnDeviceByEntity(entity1);
- assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses());
-
- deviceManager.addListener(mockListener);
- replay(mockListener);
- deviceManager.entityCleanupTask.reschedule(0, null);
-
- IDevice r = deviceManager.getDevice(d.getDeviceKey());
- assertNull(r);
- Iterator<? extends IDevice> diter =
- deviceManager.queryClassDevices(d, null, null, 1, null, null);
- assertFalse(diter.hasNext());
-
- r = deviceManager.findDevice(1L, null, null, null, null);
- assertNull(r);
-
- verify(mockListener);
- }
-
- /*
- * A ConcurrentHashMap for devices (deviceMap) that can be used to test
- * code that specially handles concurrent modification situations. In
- * particular, we overwrite values() and will replace / remove all the
- * elements returned by values.
- *
- * The remove flag in the constructor specifies if devices returned by
- * values() should be removed or replaced.
- */
- protected static class ConcurrentlyModifiedDeviceMap
- extends ConcurrentHashMap<Long, Device> {
- private static final long serialVersionUID = 7784938535441180562L;
- protected boolean remove;
- public ConcurrentlyModifiedDeviceMap(boolean remove) {
- super();
- this.remove = remove;
- }
-
- @Override
- public Collection<Device> values() {
- // Get the values from the real map and copy them since
- // the collection returned by values can reflect changed
- Collection<Device> devs = new ArrayList<Device>(super.values());
- for (Device d: devs) {
- if (remove) {
- // We remove the device from the underlying map
- super.remove(d.getDeviceKey());
- } else {
- super.remove(d.getDeviceKey());
- // We add a different Device instance with the same
- // key to the map. We'll do some hackery so the device
- // is different enough to compare differently in equals
- // but otherwise looks the same.
- // It's ugly but it works.
- Entity[] curEntities = new Entity[d.getEntities().length];
- int i = 0;
- // clone entities
- for (Entity e: d.getEntities()) {
- curEntities[i] = new Entity (e.macAddress,
- e.vlan,
- e.ipv4Address,
- e.switchDPID,
- e.switchPort,
- e.lastSeenTimestamp);
- if (e.vlan == null)
- curEntities[i].vlan = (short)1;
- else
- curEntities[i].vlan = (short)((e.vlan + 1 % 4095)+1);
- i++;
- }
- Device newDevice = new Device(d, curEntities[0]);
- newDevice.entities = curEntities;
- assertEquals(false, newDevice.equals(d));
- super.put(newDevice.getDeviceKey(), newDevice);
- }
- }
- return devs;
- }
- }
-
- @Test
- public void testEntityExpiration() throws Exception {
- doTestEntityExpiration();
- }
-
- @Test
- public void testDeviceExpiration() throws Exception {
- doTestDeviceExpiration();
- }
-
- /* Test correct entity cleanup behavior when a concurrent modification
- * occurs.
- */
- @Test
- public void testEntityExpirationConcurrentModification() throws Exception {
- deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false);
- doTestEntityExpiration();
- }
-
- /* Test correct entity cleanup behavior when a concurrent remove
- * occurs.
- */
- @Test
- public void testDeviceExpirationConcurrentRemove() throws Exception {
- deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(true);
- doTestDeviceExpiration();
- }
-
- /* Test correct entity cleanup behavior when a concurrent modification
- * occurs.
- */
- @Test
- public void testDeviceExpirationConcurrentModification() throws Exception {
- deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false);
- doTestDeviceExpiration();
- }
-
-
- @Test
- public void testAttachmentPointFlapping() throws Exception {
- Calendar c = Calendar.getInstance();
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).andReturn(true).anyTimes();
- expect(mockTopology.isBroadcastDomainPort(anyLong(),
- anyShort())).
- andReturn(false).anyTimes();
- expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
- anyLong(), anyShort())).andReturn(false).anyTimes();
- expect(mockTopology.getL2DomainId(anyLong())).
- andReturn(1L).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)1)).
- andReturn(true).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 10L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(5L, (short)1, 10L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(10L, (short)1, 1L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(5L, (short)1, 1L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(10L, (short)1, 5L, (short)1)).
- andReturn(false).anyTimes();
-
- Date topologyUpdateTime = new Date();
- expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
- anyTimes();
-
-
- replay(mockTopology);
- deviceManager.topology = mockTopology;
-
- Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime());
- Entity entity1a = new Entity(1L, null, 1, 1L, 1, c.getTime());
- Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
- Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
- entity1.setLastSeenTimestamp(c.getTime());
- c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
- entity1a.setLastSeenTimestamp(c.getTime());
- c.add(Calendar.MILLISECOND, 1);
- entity2.setLastSeenTimestamp(c.getTime());
- c.add(Calendar.MILLISECOND, 1);
- entity3.setLastSeenTimestamp(c.getTime());
-
-
-
- IDevice d;
- d = deviceManager.learnDeviceByEntity(entity1);
- d = deviceManager.learnDeviceByEntity(entity1a);
- d = deviceManager.learnDeviceByEntity(entity2);
- d = deviceManager.learnDeviceByEntity(entity3);
-
- // all entities are active, so entity3 should win
- assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
- d.getAttachmentPoints());
-
- assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1),},
- d.getAttachmentPoints(true));
-
- c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/4);
- entity1.setLastSeenTimestamp(c.getTime());
- d = deviceManager.learnDeviceByEntity(entity1);
-
- // all are still active; entity3 should still win
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
- d.getAttachmentPoints());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 1,
- ErrorStatus.DUPLICATE_DEVICE),
- new SwitchPort(10L, 1,
- ErrorStatus.DUPLICATE_DEVICE) },
- d.getAttachmentPoints(true));
-
- c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+2000);
- entity1.setLastSeenTimestamp(c.getTime());
- d = deviceManager.learnDeviceByEntity(entity1);
-
- assertEquals(entity1.getActiveSince(), entity1.getLastSeenTimestamp());
- // entity1 should now be the only active entity
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
- d.getAttachmentPoints());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
- d.getAttachmentPoints(true));
- }
-
-
- @Test
- public void testAttachmentPointFlappingTwoCluster() throws Exception {
- Calendar c = Calendar.getInstance();
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).andReturn(true).anyTimes();
- expect(mockTopology.isBroadcastDomainPort(anyLong(),
- anyShort())).
- andReturn(false).anyTimes();
- expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
- anyLong(), anyShort())).andReturn(false).anyTimes();
- expect(mockTopology.getL2DomainId(1L)).
- andReturn(1L).anyTimes();
- expect(mockTopology.getL2DomainId(5L)).
- andReturn(5L).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)2)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)2, 5L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(5L, (short)1, 5L, (short)2)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)2, 1L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)2)).
- andReturn(false).anyTimes();
- expect(mockTopology.isConsistent(5L, (short)2, 5L, (short)1)).
- andReturn(false).anyTimes();
-
- Date topologyUpdateTime = new Date();
- expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
- anyTimes();
-
- replay(mockTopology);
- deviceManager.topology = mockTopology;
-
- Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime());
- Entity entity2 = new Entity(1L, null, null, 1L, 2, c.getTime());
- Entity entity3 = new Entity(1L, null, null, 5L, 1, c.getTime());
- Entity entity4 = new Entity(1L, null, null, 5L, 2, c.getTime());
- entity1.setLastSeenTimestamp(c.getTime());
- c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
- c.add(Calendar.MILLISECOND, 1);
- entity2.setLastSeenTimestamp(c.getTime());
- c.add(Calendar.MILLISECOND, 1);
- entity3.setLastSeenTimestamp(c.getTime());
- c.add(Calendar.MILLISECOND, 1);
- entity4.setLastSeenTimestamp(c.getTime());
-
- deviceManager.learnDeviceByEntity(entity1);
- deviceManager.learnDeviceByEntity(entity2);
- deviceManager.learnDeviceByEntity(entity3);
- IDevice d = deviceManager.learnDeviceByEntity(entity4);
-
- // all entities are active, so entities 2,4 should win
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2),
- new SwitchPort(5L, 2) },
- d.getAttachmentPoints());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2),
- new SwitchPort(5L, 2)},
- d.getAttachmentPoints(true));
-
- c.add(Calendar.MILLISECOND, 1);
- entity1.setLastSeenTimestamp(c.getTime());
- d = deviceManager.learnDeviceByEntity(entity1);
-
- // all entities are active, so entities 2,4 should win
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 2) },
- d.getAttachmentPoints());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 2),
- new SwitchPort(1L, 2, ErrorStatus.DUPLICATE_DEVICE)},
- d.getAttachmentPoints(true));
-
- c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+1);
- entity1.setLastSeenTimestamp(c.getTime());
- d = deviceManager.learnDeviceByEntity(entity1);
-
- // entities 3,4 are still in conflict, but 1 should be resolved
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 2) },
- d.getAttachmentPoints());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 2)},
- d.getAttachmentPoints(true));
-
- entity3.setLastSeenTimestamp(c.getTime());
- d = deviceManager.learnDeviceByEntity(entity3);
-
- // no conflicts, 1 and 3 will win
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 1) },
- d.getAttachmentPoints());
- assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
- new SwitchPort(5L, 1) },
- d.getAttachmentPoints(true));
-
- }
-
- protected void doTestDeviceQuery() throws Exception {
- Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
- Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
- Entity entity3 = new Entity(3L, (short)3, 3, 5L, 1, new Date());
- Entity entity4 = new Entity(4L, (short)4, 3, 5L, 2, new Date());
- Entity entity5 = new Entity(1L, (short)4, 3, 5L, 2, new Date());
-
- deviceManager.learnDeviceByEntity(entity1);
- deviceManager.learnDeviceByEntity(entity2);
- deviceManager.learnDeviceByEntity(entity3);
- deviceManager.learnDeviceByEntity(entity4);
-
- Iterator<? extends IDevice> iter =
- deviceManager.queryDevices(null, (short)1, 1, null, null);
- int count = 0;
- while (iter.hasNext()) {
- count += 1;
- iter.next();
- }
- assertEquals(1, count);
-
- iter = deviceManager.queryDevices(null, (short)3, 3, null, null);
- count = 0;
- while (iter.hasNext()) {
- count += 1;
- iter.next();
- }
- assertEquals(1, count);
-
- iter = deviceManager.queryDevices(null, (short)1, 3, null, null);
- count = 0;
- while (iter.hasNext()) {
- count += 1;
- iter.next();
- }
- assertEquals(0, count);
-
- deviceManager.learnDeviceByEntity(entity5);
- iter = deviceManager.queryDevices(null, (short)4, 3, null, null);
- count = 0;
- while (iter.hasNext()) {
- count += 1;
- iter.next();
- }
- assertEquals(2, count);
- }
-
- @Test
- public void testDeviceIndex() throws Exception {
- EnumSet<IDeviceService.DeviceField> indexFields =
- EnumSet.noneOf(IDeviceService.DeviceField.class);
- indexFields.add(IDeviceService.DeviceField.IPV4);
- indexFields.add(IDeviceService.DeviceField.VLAN);
- deviceManager.addIndex(false, indexFields);
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
- replay(mockTopology);
- doTestDeviceQuery();
- }
-
- @Test
- public void testDeviceQuery() throws Exception {
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
- replay(mockTopology);
-
- doTestDeviceQuery();
- }
-
- protected void doTestDeviceClassQuery() throws Exception {
- Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
- Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
- Entity entity3 = new Entity(3L, (short)3, 3, 5L, 1, new Date());
- Entity entity4 = new Entity(4L, (short)4, 3, 5L, 2, new Date());
- Entity entity5 = new Entity(1L, (short)4, 3, 5L, 2, new Date());
-
- IDevice d = deviceManager.learnDeviceByEntity(entity1);
- deviceManager.learnDeviceByEntity(entity2);
- deviceManager.learnDeviceByEntity(entity3);
- deviceManager.learnDeviceByEntity(entity4);
-
- Iterator<? extends IDevice> iter =
- deviceManager.queryClassDevices(d, null,
- (short)1, 1, null, null);
- int count = 0;
- while (iter.hasNext()) {
- count += 1;
- iter.next();
- }
- assertEquals(1, count);
-
- iter = deviceManager.queryClassDevices(d, null,
- (short)3, 3, null, null);
- count = 0;
- while (iter.hasNext()) {
- count += 1;
- iter.next();
- }
- assertEquals(1, count);
-
- iter = deviceManager.queryClassDevices(d, null,
- (short)1, 3, null, null);
- count = 0;
- while (iter.hasNext()) {
- count += 1;
- iter.next();
- }
- assertEquals(0, count);
-
- deviceManager.learnDeviceByEntity(entity5);
- iter = deviceManager.queryClassDevices(d, null,
- (short)4, 3, null, null);
- count = 0;
- while (iter.hasNext()) {
- count += 1;
- iter.next();
- }
- assertEquals(2, count);
- }
-
- @Test
- public void testDeviceClassIndex() throws Exception {
- EnumSet<IDeviceService.DeviceField> indexFields =
- EnumSet.noneOf(IDeviceService.DeviceField.class);
- indexFields.add(IDeviceService.DeviceField.IPV4);
- indexFields.add(IDeviceService.DeviceField.VLAN);
- deviceManager.addIndex(true, indexFields);
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
- replay(mockTopology);
-
- doTestDeviceClassQuery();
- }
-
- @Test
- public void testDeviceClassQuery() throws Exception {
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
- replay(mockTopology);
-
- doTestDeviceClassQuery();
- }
-
- @Test
- public void testFindDevice() {
- boolean exceptionCaught;
- deviceManager.entityClassifier= new MockEntityClassifierMac();
- deviceManager.startUp(null);
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
- replay(mockTopology);
-
- Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
- Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
- Entity entity2b = new Entity(22L, (short)2, 2, 1L, 2, new Date());
-
- Entity entity3 = new Entity(3L, (short)1, 3, 2L, 1, new Date());
- Entity entity4 = new Entity(4L, (short)2, 4, 2L, 2, new Date());
-
- Entity entity5 = new Entity(5L, (short)1, 5, 3L, 1, new Date());
-
-
- IDevice d1 = deviceManager.learnDeviceByEntity(entity1);
- IDevice d2 = deviceManager.learnDeviceByEntity(entity2);
- IDevice d3 = deviceManager.learnDeviceByEntity(entity3);
- IDevice d4 = deviceManager.learnDeviceByEntity(entity4);
- IDevice d5 = deviceManager.learnDeviceByEntity(entity5);
-
- // Make sure the entity classifier worked as expected
- assertEquals(MockEntityClassifierMac.testECMac1, d1.getEntityClass());
- assertEquals(MockEntityClassifierMac.testECMac1, d2.getEntityClass());
- assertEquals(MockEntityClassifierMac.testECMac2, d3.getEntityClass());
- assertEquals(MockEntityClassifierMac.testECMac2, d4.getEntityClass());
- assertEquals(DefaultEntityClassifier.entityClass,
- d5.getEntityClass());
-
- // Look up the device using findDevice() which uses only the primary
- // index
- assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(),
- entity1.getVlan(),
- entity1.getIpv4Address(),
- entity1.getSwitchDPID(),
- entity1.getSwitchPort()));
- // port changed. Device will be found through class index
- assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(),
- entity1.getVlan(),
- entity1.getIpv4Address(),
- entity1.getSwitchDPID(),
- entity1.getSwitchPort()+1));
- // VLAN changed. No device matches
- assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(),
- (short)42,
- entity1.getIpv4Address(),
- entity1.getSwitchDPID(),
- entity1.getSwitchPort()));
- assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(),
- null,
- entity1.getIpv4Address(),
- entity1.getSwitchDPID(),
- entity1.getSwitchPort()));
- assertEquals(d2, deviceManager.findDeviceByEntity(entity2));
- assertEquals(null, deviceManager.findDeviceByEntity(entity2b));
- assertEquals(d3, deviceManager.findDevice(entity3.getMacAddress(),
- entity3.getVlan(),
- entity3.getIpv4Address(),
- entity3.getSwitchDPID(),
- entity3.getSwitchPort()));
- // switch and port not set. throws exception
- exceptionCaught = false;
- try {
- assertEquals(null, deviceManager.findDevice(entity3.getMacAddress(),
- entity3.getVlan(),
- entity3.getIpv4Address(),
- null,
- null));
- }
- catch (IllegalArgumentException e) {
- exceptionCaught = true;
- }
- if (!exceptionCaught)
- fail("findDevice() did not throw IllegalArgumentException");
- assertEquals(d4, deviceManager.findDeviceByEntity(entity4));
- assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(),
- entity5.getVlan(),
- entity5.getIpv4Address(),
- entity5.getSwitchDPID(),
- entity5.getSwitchPort()));
- // switch and port not set. throws exception (swith/port are key
- // fields of IEntityClassifier but not d5.entityClass
- exceptionCaught = false;
- try {
- assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(),
- entity5.getVlan(),
- entity5.getIpv4Address(),
- null,
- null));
- }
- catch (IllegalArgumentException e) {
- exceptionCaught = true;
- }
- if (!exceptionCaught)
- fail("findDevice() did not throw IllegalArgumentException");
-
-
- Entity entityNoClass = new Entity(5L, (short)1, 5, -1L, 1, new Date());
- assertEquals(null, deviceManager.findDeviceByEntity(entityNoClass));
-
-
- // Now look up destination devices
- assertEquals(d1, deviceManager.findDestDevice(d2,
- entity1.getMacAddress(),
- entity1.getVlan(),
- entity1.getIpv4Address()));
- assertEquals(d1, deviceManager.findDestDevice(d2,
- entity1.getMacAddress(),
- entity1.getVlan(),
- null));
- assertEquals(null, deviceManager.findDestDevice(d2,
- entity1.getMacAddress(),
- (short) -1,
- 0));
- }
-
- @Test
- public void testGetIPv4Addresses() {
- // Looks like Date is only 1s granularity
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes();
- expect(mockTopology.isConsistent(EasyMock.anyLong(),
- EasyMock.anyShort(),
- EasyMock.anyLong(),
- EasyMock.anyShort()))
- .andReturn(false)
- .anyTimes();
- expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
- EasyMock.anyShort()))
- .andReturn(false)
- .anyTimes();
- expect(mockTopology.isInSameBroadcastDomain(EasyMock.anyLong(),
- EasyMock.anyShort(),
- EasyMock.anyLong(),
- EasyMock.anyShort())).
- andReturn(false).anyTimes();
- replay(mockTopology);
-
- Entity e1 = new Entity(1L, (short)1, null, null, null, new Date(2000));
- Device d1 = deviceManager.learnDeviceByEntity(e1);
- assertArrayEquals(new Integer[0], d1.getIPv4Addresses());
-
-
- Entity e2 = new Entity(2L, (short)2, 2, null, null, new Date(2000));
- Device d2 = deviceManager.learnDeviceByEntity(e2);
- d2 = deviceManager.learnDeviceByEntity(e2);
- assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
- // More than one entity
- Entity e2b = new Entity(2L, (short)2, null, 2L, 2, new Date(3000));
- d2 = deviceManager.learnDeviceByEntity(e2b);
- assertEquals(2, d2.entities.length);
- assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
- // and now add an entity with an IP
- Entity e2c = new Entity(2L, (short)2, 2, 2L, 3, new Date(3000));
- d2 = deviceManager.learnDeviceByEntity(e2c);
- assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
- assertEquals(3, d2.entities.length);
-
- // Other devices with different IPs shouldn't interfere
- Entity e3 = new Entity(3L, (short)3, 3, null, null, new Date(4000));
- Entity e3b = new Entity(3L, (short)3, 3, 3L, 3, new Date(4400));
- Device d3 = deviceManager.learnDeviceByEntity(e3);
- d3 = deviceManager.learnDeviceByEntity(e3b);
- assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
- assertArrayEquals(new Integer[] { 3 }, d3.getIPv4Addresses());
-
- // Add another IP to d3
- Entity e3c = new Entity(3L, (short)3, 33, 3L, 3, new Date(4400));
- d3 = deviceManager.learnDeviceByEntity(e3c);
- Integer[] ips = d3.getIPv4Addresses();
- Arrays.sort(ips);
- assertArrayEquals(new Integer[] { 3, 33 }, ips);
-
- // Add another device that also claims IP2 but is older than e2
- Entity e4 = new Entity(4L, (short)4, 2, null, null, new Date(1000));
- Entity e4b = new Entity(4L, (short)4, null, 4L, 4, new Date(1000));
- Device d4 = deviceManager.learnDeviceByEntity(e4);
- assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
- assertArrayEquals(new Integer[0], d4.getIPv4Addresses());
- // add another entity to d4
- d4 = deviceManager.learnDeviceByEntity(e4b);
- assertArrayEquals(new Integer[0], d4.getIPv4Addresses());
-
- // Make e4 and e4a newer
- Entity e4c = new Entity(4L, (short)4, 2, null, null, new Date(5000));
- Entity e4d = new Entity(4L, (short)4, null, 4L, 5, new Date(5000));
- d4 = deviceManager.learnDeviceByEntity(e4c);
- d4 = deviceManager.learnDeviceByEntity(e4d);
- assertArrayEquals(new Integer[0], d2.getIPv4Addresses());
- // FIXME: d4 should not return IP4
- assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses());
-
- // Add another newer entity to d2 but with different IP
- Entity e2d = new Entity(2L, (short)2, 22, 4L, 6, new Date(6000));
- d2 = deviceManager.learnDeviceByEntity(e2d);
- assertArrayEquals(new Integer[] { 22 }, d2.getIPv4Addresses());
- assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses());
-
- // new IP for d2,d4 but with same timestamp. Both devices get the IP
- Entity e2e = new Entity(2L, (short)2, 42, 2L, 4, new Date(7000));
- d2 = deviceManager.learnDeviceByEntity(e2e);
- ips= d2.getIPv4Addresses();
- Arrays.sort(ips);
- assertArrayEquals(new Integer[] { 22, 42 }, ips);
- Entity e4e = new Entity(4L, (short)4, 42, 4L, 7, new Date(7000));
- d4 = deviceManager.learnDeviceByEntity(e4e);
- ips= d4.getIPv4Addresses();
- Arrays.sort(ips);
- assertArrayEquals(new Integer[] { 2, 42 }, ips);
-
- // add a couple more IPs
- Entity e2f = new Entity(2L, (short)2, 4242, 2L, 5, new Date(8000));
- d2 = deviceManager.learnDeviceByEntity(e2f);
- ips= d2.getIPv4Addresses();
- Arrays.sort(ips);
- assertArrayEquals(new Integer[] { 22, 42, 4242 }, ips);
- Entity e4f = new Entity(4L, (short)4, 4242, 4L, 8, new Date(9000));
- d4 = deviceManager.learnDeviceByEntity(e4f);
- ips= d4.getIPv4Addresses();
- Arrays.sort(ips);
- assertArrayEquals(new Integer[] { 2, 42, 4242 }, ips);
- }
-
- // TODO: this test should really go into a separate class that collects
- // unit tests for Device
- @Test
- public void testGetSwitchPortVlanId() {
- Entity entity1 = new Entity(1L, (short)1, null, 10L, 1, new Date());
- Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date());
- Entity entity3 = new Entity(1L, (short)3, null, 1L, 1, new Date());
- Entity entity4 = new Entity(1L, (short)42, null, 1L, 1, new Date());
- Entity[] entities = new Entity[] { entity1, entity2,
- entity3, entity4
- };
- Device d = new Device(null,1L, null, null, Arrays.asList(entities), null);
- SwitchPort swp1x1 = new SwitchPort(1L, 1);
- SwitchPort swp1x2 = new SwitchPort(1L, 2);
- SwitchPort swp2x1 = new SwitchPort(2L, 1);
- SwitchPort swp10x1 = new SwitchPort(10L, 1);
- assertArrayEquals(new Short[] { -1, 1},
- d.getSwitchPortVlanIds(swp10x1));
- assertArrayEquals(new Short[] { 3, 42},
- d.getSwitchPortVlanIds(swp1x1));
- assertArrayEquals(new Short[0],
- d.getSwitchPortVlanIds(swp1x2));
- assertArrayEquals(new Short[0],
- d.getSwitchPortVlanIds(swp2x1));
- }
-
- @Test
- public void testReclassifyDevice() {
- MockFlexEntityClassifier flexClassifier =
- new MockFlexEntityClassifier();
- deviceManager.entityClassifier= flexClassifier;
- deviceManager.startUp(null);
-
- ITopologyService mockTopology = createMock(ITopologyService.class);
- deviceManager.topology = mockTopology;
- expect(mockTopology.isAttachmentPointPort(anyLong(),
- anyShort())).
- andReturn(true).anyTimes();
- expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes();
- expect(mockTopology.isConsistent(EasyMock.anyLong(),
- EasyMock.anyShort(),
- EasyMock.anyLong(),
- EasyMock.anyShort()))
- .andReturn(false)
- .anyTimes();
- expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
- EasyMock.anyShort()))
- .andReturn(false)
- .anyTimes();
- replay(mockTopology);
-
- //flexClassifier.createTestEntityClass("Class1");
-
- Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
- Entity entity1b = new Entity(1L, (short)2, 1, 1L, 1, new Date());
- Entity entity2 = new Entity(2L, (short)1, 2, 2L, 2, new Date());
- Entity entity2b = new Entity(2L, (short)2, 2, 2L, 2, new Date());
-
-
- Device d1 = deviceManager.learnDeviceByEntity(entity1);
- Device d2 = deviceManager.learnDeviceByEntity(entity2);
- Device d1b = deviceManager.learnDeviceByEntity(entity1b);
- Device d2b = deviceManager.learnDeviceByEntity(entity2b);
-
- d1 = deviceManager.getDeviceIteratorForQuery(entity1.getMacAddress(),
- entity1.getVlan(), entity1.getIpv4Address(),
- entity1.getSwitchDPID(), entity1.getSwitchPort())
- .next();
- d1b = deviceManager.getDeviceIteratorForQuery(entity1b.getMacAddress(),
- entity1b.getVlan(), entity1b.getIpv4Address(),
- entity1b.getSwitchDPID(), entity1b.getSwitchPort()).next();
-
- assertEquals(d1, d1b);
-
- d2 = deviceManager.getDeviceIteratorForQuery(entity2.getMacAddress(),
- entity2.getVlan(), entity2.getIpv4Address(),
- entity2.getSwitchDPID(), entity2.getSwitchPort()).next();
- d2b = deviceManager.getDeviceIteratorForQuery(entity2b.getMacAddress(),
- entity2b.getVlan(), entity2b.getIpv4Address(),
- entity2b.getSwitchDPID(), entity2b.getSwitchPort()).next();
- assertEquals(d2, d2b);
-
- IEntityClass eC1 = flexClassifier.createTestEntityClass("C1");
- IEntityClass eC2 = flexClassifier.createTestEntityClass("C2");
-
- flexClassifier.addVlanEntities((short)1, eC1);
- flexClassifier.addVlanEntities((short)2, eC1);
-
- deviceManager.reclassifyDevice(d1);
- deviceManager.reclassifyDevice(d2);
-
- d1 = deviceManager.deviceMap.get(
- deviceManager.primaryIndex.findByEntity(entity1));
- d1b = deviceManager.deviceMap.get(
- deviceManager.primaryIndex.findByEntity(entity1b));
-
- assertEquals(d1, d1b);
-
- d2 = deviceManager.deviceMap.get(
- deviceManager.primaryIndex.findByEntity(entity2));
- d2b = deviceManager.deviceMap.get(
- deviceManager.primaryIndex.findByEntity(entity2b));
-
- assertEquals(d2, d2b);
-
- flexClassifier.addVlanEntities((short)1, eC2);
-
- deviceManager.reclassifyDevice(d1);
- deviceManager.reclassifyDevice(d2);
- d1 = deviceManager.deviceMap.get(
- deviceManager.primaryIndex.findByEntity(entity1));
- d1b = deviceManager.deviceMap.get(
- deviceManager.primaryIndex.findByEntity(entity1b));
- d2 = deviceManager.deviceMap.get(
- deviceManager.primaryIndex.findByEntity(entity2));
- d2b = deviceManager.deviceMap.get(
- deviceManager.primaryIndex.findByEntity(entity2b));
-
- assertNotSame(d1, d1b);
-
- assertNotSame(d2, d2b);
-
- flexClassifier.addVlanEntities((short)1, eC1);
- deviceManager.reclassifyDevice(d1);
- deviceManager.reclassifyDevice(d2);
- ClassState classState = deviceManager.classStateMap.get(eC1.getName());
-
- Long deviceKey1 = null;
- Long deviceKey1b = null;
- Long deviceKey2 = null;
- Long deviceKey2b = null;
-
- deviceKey1 =
- classState.classIndex.findByEntity(entity1);
- deviceKey1b =
- classState.classIndex.findByEntity(entity1b);
- deviceKey2 =
- classState.classIndex.findByEntity(entity2);
- deviceKey2b =
- classState.classIndex.findByEntity(entity2b);
-
- assertEquals(deviceKey1, deviceKey1b);
-
- assertEquals(deviceKey2, deviceKey2b);
-
-
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java
deleted file mode 100644
index 2a6ee9d..0000000
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
-* Copyright 2012 Big Switch Networks, Inc.
-*
-* 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.Iterator;
-
-import org.junit.Test;
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import junit.framework.TestCase;
-
-/**
- *
- * @author gregor
- *
- */
-public class DeviceUniqueIndexTest extends TestCase {
- protected Entity e1a;
- protected Entity e1b;
- protected Device d1;
- protected Entity e2;
- protected Entity e2alt;
- protected Entity e3;
- protected Entity e4;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- e1a = new Entity(1L, (short)1, 1, 1L, 1, new Date());
- e1b = new Entity(1L, (short)2, 1, 1L, 1, new Date());
- List<Entity> d1Entities = new ArrayList<Entity>(2);
- d1Entities.add(e1a);
- d1Entities.add(e1b);
- d1 = new Device(null, Long.valueOf(1), null, null, d1Entities, null);
-
- // e2 and e2 alt match in MAC and VLAN
- e2 = new Entity(2L, (short)2, 2, 2L, 2, new Date());
- e2alt = new Entity(2, (short)2, null, null, null, null);
-
- // IP is null
- e3 = new Entity(3L, (short)3, null, 3L, 3, new Date());
-
- // IP and switch and port are null
- e4 = new Entity(4L, (short)4, null, null, null, new Date());
- }
-
- /*
- * Checks that the iterator it returns the elements in the Set expected
- * Doesn't check how often an element is returned as long it's at least
- * once
- */
- protected void verifyIterator(Set<Long> expected, Iterator<Long> it) {
- HashSet<Long> actual = new HashSet<Long>();
- while (it.hasNext()) {
- actual.add(it.next());
- }
- assertEquals(expected, actual);
- }
-
- @Test
- public void testDeviceUniqueIndex() {
- DeviceUniqueIndex idx1 = new DeviceUniqueIndex(
- EnumSet.of(DeviceField.MAC,
- DeviceField.VLAN));
-
- idx1.updateIndex(d1, d1.getDeviceKey());
- idx1.updateIndex(e2, 2L);
-
- //-------------
- // Test findByEntity lookups
- assertEquals(Long.valueOf(1L), idx1.findByEntity(e1a));
- assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b));
- assertEquals(Long.valueOf(2L), idx1.findByEntity(e2));
- // we didn't add e2alt but since they key fields are the same we
- // should find it
- assertEquals(Long.valueOf(2L), idx1.findByEntity(e2alt));
- assertEquals(null, idx1.findByEntity(e3));
- assertEquals(null, idx1.findByEntity(e4));
-
- //-------------
- // Test getAll()
- HashSet<Long> expectedKeys = new HashSet<Long>();
- expectedKeys.add(1L);
- expectedKeys.add(2L);
- verifyIterator(expectedKeys, idx1.getAll());
-
-
- //-------------
- // Test queryByEntity()
- verifyIterator(Collections.<Long>singleton(1L),
- idx1.queryByEntity(e1a));
- verifyIterator(Collections.<Long>singleton(1L),
- idx1.queryByEntity(e1b));
- verifyIterator(Collections.<Long>singleton(2L),
- idx1.queryByEntity(e2));
- verifyIterator(Collections.<Long>singleton(2L),
- idx1.queryByEntity(e2alt));
- assertEquals(false, idx1.queryByEntity(e3).hasNext());
- assertEquals(false, idx1.queryByEntity(e3).hasNext());
-
-
- //-------------
- // Test removal
- idx1.removeEntity(e1a, 42L); // No-op. e1a isn't mapped to this key
- assertEquals(Long.valueOf(1L), idx1.findByEntity(e1a));
- idx1.removeEntity(e1a, 1L);
- assertEquals(null, idx1.findByEntity(e1a));
- assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b));
- assertEquals(Long.valueOf(2L), idx1.findByEntity(e2));
- idx1.removeEntity(e2);
- assertEquals(null, idx1.findByEntity(e2));
- assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b));
-
-
- //-------------
- // Test null keys
- DeviceUniqueIndex idx2 = new DeviceUniqueIndex(
- EnumSet.of(DeviceField.IPV4,
- DeviceField.SWITCH));
- // only one key field is null
- idx2.updateIndex(e3, 3L);
- assertEquals(Long.valueOf(3L), idx2.findByEntity(e3));
- e3.ipv4Address = 3;
- assertEquals(null, idx2.findByEntity(e3));
- // all key fields are null
- idx2.updateIndex(e4, 4L);
- assertEquals(null, idx2.findByEntity(e4));
- Device d4 = new Device(null, 4L, null, null, Collections.<Entity>singleton(e4), null);
- idx2.updateIndex(d4, 4L);
- assertEquals(null, idx2.findByEntity(e4));
-
-
-
- //-------------
- // entity already exists with different deviceKey
- DeviceUniqueIndex idx3 = new DeviceUniqueIndex(
- EnumSet.of(DeviceField.MAC,
- DeviceField.VLAN));
- idx3.updateIndex(e1a, 42L);
- assertEquals(false, idx3.updateIndex(d1, 1L));
- // TODO: shouldn't this fail as well so that the behavior
- // is consistent?
- idx3.updateIndex(e1a, 1L);
- // anyways. We can now add d1 ;-)
- assertEquals(true, idx3.updateIndex(d1, 1L));
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java
deleted file mode 100644
index 5460ea3..0000000
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
-* Copyright 2011,2012 Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.test;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.TreeSet;
-
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.devicemanager.internal.AttachmentPoint;
-import net.floodlightcontroller.devicemanager.internal.Device;
-import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl;
-import net.floodlightcontroller.devicemanager.internal.Entity;
-
-/**
- * This mock device removes the dependency on topology and a parent device
- * manager and simply assumes all its entities are current and correct
- */
-public class MockDevice extends Device {
-
- public MockDevice(DeviceManagerImpl deviceManager,
- Long deviceKey,
- Entity entity,
- IEntityClass entityClass) {
- super(deviceManager, deviceKey, entity, entityClass);
- }
-
- public MockDevice(Device device, Entity newEntity) {
- super(device, newEntity);
- }
-
- public MockDevice(DeviceManagerImpl deviceManager, Long deviceKey,
- List<AttachmentPoint> aps,
- List<AttachmentPoint> trueAPs,
- Collection<Entity> entities,
- IEntityClass entityClass) {
- super(deviceManager, deviceKey, aps, trueAPs, entities, entityClass);
- }
-
- @Override
- public Integer[] getIPv4Addresses() {
- TreeSet<Integer> vals = new TreeSet<Integer>();
- for (Entity e : entities) {
- if (e.getIpv4Address() == null) continue;
- vals.add(e.getIpv4Address());
- }
-
- return vals.toArray(new Integer[vals.size()]);
- }
-
- @Override
- public SwitchPort[] getAttachmentPoints() {
- ArrayList<SwitchPort> vals =
- new ArrayList<SwitchPort>(entities.length);
- for (Entity e : entities) {
- if (e.getSwitchDPID() != null &&
- e.getSwitchPort() != null &&
- deviceManager.isValidAttachmentPoint(e.getSwitchDPID(), e.getSwitchPort())) {
- SwitchPort sp = new SwitchPort(e.getSwitchDPID(),
- e.getSwitchPort());
- vals.add(sp);
- }
- }
- return vals.toArray(new SwitchPort[vals.size()]);
- }
-
- @Override
- public String toString() {
- String rv = "MockDevice[entities=+";
- rv += entities.toString();
- rv += "]";
- return rv;
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
deleted file mode 100644
index 8b539f6..0000000
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
+++ /dev/null
@@ -1,103 +0,0 @@
-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;
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.IEntityClassifierService;
-import net.floodlightcontroller.devicemanager.internal.AttachmentPoint;
-import net.floodlightcontroller.devicemanager.internal.Device;
-import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl;
-import net.floodlightcontroller.devicemanager.internal.Entity;
-
-/**
- * Mock device manager useful for unit tests
- * @author readams
- */
-public class MockDeviceManager extends DeviceManagerImpl {
- /**
- * Set a new IEntityClassifier
- * Use this as a quick way to use a particular entity classifier in a
- * single test without having to setup the full FloodlightModuleContext
- * again.
- * @param ecs
- */
- public void setEntityClassifier(IEntityClassifierService ecs) {
- this.entityClassifier = ecs;
- this.startUp(null);
- }
-
- /**
- * Learn a device using the given characteristics.
- * @param macAddress the MAC
- * @param vlan the VLAN (can be null)
- * @param ipv4Address the IP (can be null)
- * @param switchDPID the attachment point switch DPID (can be null)
- * @param switchPort the attachment point switch port (can be null)
- * @param processUpdates if false, will not send updates. Note that this
- * method is not thread safe if this is false
- * @return the device, either new or not
- */
- public IDevice learnEntity(long macAddress, Short vlan,
- Integer ipv4Address, Long switchDPID,
- Integer switchPort,
- boolean processUpdates) {
- Set<IDeviceListener> listeners = deviceListeners;
- if (!processUpdates) {
- deviceListeners = Collections.<IDeviceListener>emptySet();
- }
-
- if (vlan != null && vlan.shortValue() <= 0)
- vlan = null;
- if (ipv4Address != null && ipv4Address == 0)
- ipv4Address = null;
- IDevice res = learnDeviceByEntity(new Entity(macAddress, vlan,
- ipv4Address, switchDPID,
- switchPort, new Date()));
- deviceListeners = listeners;
- return res;
- }
-
- /**
- * Learn a device using the given characteristics.
- * @param macAddress the MAC
- * @param vlan the VLAN (can be null)
- * @param ipv4Address the IP (can be null)
- * @param switchDPID the attachment point switch DPID (can be null)
- * @param switchPort the attachment point switch port (can be null)
- * @return the device, either new or not
- */
- public IDevice learnEntity(long macAddress, Short vlan,
- Integer ipv4Address, Long switchDPID,
- Integer switchPort) {
- return learnEntity(macAddress, vlan, ipv4Address,
- switchDPID, switchPort, true);
- }
-
- @Override
- protected Device allocateDevice(Long deviceKey,
- Entity entity,
- IEntityClass entityClass) {
- return new MockDevice(this, deviceKey, entity, entityClass);
- }
-
- @Override
- protected Device allocateDevice(Long deviceKey,
- List<AttachmentPoint> aps,
- List<AttachmentPoint> trueAPs,
- Collection<Entity> entities,
- IEntityClass entityClass) {
- return new MockDevice(this, deviceKey, aps, trueAPs, entities, entityClass);
- }
-
- @Override
- protected Device allocateDevice(Device device,
- Entity entity) {
- return new MockDevice(device, entity);
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifier.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifier.java
deleted file mode 100644
index 679dc9a..0000000
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifier.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.floodlightcontroller.devicemanager.test;
-
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.MAC;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.PORT;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.SWITCH;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.VLAN;
-
-import java.util.EnumSet;
-
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.internal.Entity;
-
-/** A simple IEntityClassifier. Useful for tests that need IEntityClassifiers
- * and IEntityClass'es with switch and/or port key fields
- */
-public class MockEntityClassifier extends DefaultEntityClassifier {
- public static class TestEntityClass implements IEntityClass {
- @Override
- public EnumSet<DeviceField> getKeyFields() {
- return EnumSet.of(MAC, VLAN, SWITCH, PORT);
- }
-
- @Override
- public String getName() {
- return "TestEntityClass";
- }
- }
- public static IEntityClass testEC =
- new MockEntityClassifier.TestEntityClass();
-
- @Override
- public IEntityClass classifyEntity(Entity entity) {
- if (entity.getSwitchDPID() >= 10L) {
- return testEC;
- }
- return DefaultEntityClassifier.entityClass;
- }
-
- @Override
- public EnumSet<IDeviceService.DeviceField> getKeyFields() {
- return EnumSet.of(MAC, VLAN, SWITCH, PORT);
- }
-
-}
\ No newline at end of file
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifierMac.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifierMac.java
deleted file mode 100644
index 398b6c0..0000000
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifierMac.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package net.floodlightcontroller.devicemanager.test;
-
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.MAC;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.PORT;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.SWITCH;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.VLAN;
-
-import java.util.EnumSet;
-
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.internal.Entity;
-
-/** A simple IEntityClassifier. Useful for tests that need an IEntityClassifier
- * with switch/port as key fields.
- */
-public class MockEntityClassifierMac extends DefaultEntityClassifier {
- public static class TestEntityClassMac implements IEntityClass {
- protected String name;
- public TestEntityClassMac(String name) {
- this.name = name;
- }
-
- @Override
- public EnumSet<DeviceField> getKeyFields() {
- return EnumSet.of(MAC, VLAN);
- }
-
- @Override
- public String getName() {
- return name;
- }
- }
- public static IEntityClass testECMac1 =
- new MockEntityClassifierMac.TestEntityClassMac("testECMac1");
- public static IEntityClass testECMac2 =
- new MockEntityClassifierMac.TestEntityClassMac("testECMac2");
-
- @Override
- public IEntityClass classifyEntity(Entity entity) {
- if (entity.getSwitchDPID() == 1L) {
- return testECMac1;
- } else if (entity.getSwitchDPID() == 2L) {
- return testECMac2;
- } else if (entity.getSwitchDPID() == -1L) {
- return null;
- }
- return DefaultEntityClassifier.entityClass;
- }
-
- @Override
- public EnumSet<IDeviceService.DeviceField> getKeyFields() {
- return EnumSet.of(MAC, VLAN, SWITCH, PORT);
- }
-}
\ No newline at end of file
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockFlexEntityClassifier.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockFlexEntityClassifier.java
deleted file mode 100644
index 2224551..0000000
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockFlexEntityClassifier.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- *
- */
-package net.floodlightcontroller.devicemanager.test;
-
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.MAC;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.PORT;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.SWITCH;
-import static net.floodlightcontroller.devicemanager.IDeviceService.DeviceField.VLAN;
-
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClass;
-import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.internal.Entity;
-
-/**
- * Extension to simple entity classifier to help in unit tests to provide table
- * based multiple entity classification mock for reclassification tests
- *
- */
-public class MockFlexEntityClassifier extends DefaultEntityClassifier {
- Map <Long, IEntityClass> switchEntities;
- Map <Short, IEntityClass> vlanEntities;
-
- public static class TestEntityClass implements IEntityClass {
- String name;
- public TestEntityClass(String name) {
- this.name = name;
- }
- @Override
- public EnumSet<DeviceField> getKeyFields() {
- return EnumSet.of(MAC);
- }
-
- @Override
- public String getName() {
- return name;
- }
- }
- public static IEntityClass defaultClass = new TestEntityClass("default");
- public MockFlexEntityClassifier() {
- switchEntities = new HashMap<Long, IEntityClass> ();
- vlanEntities = new HashMap<Short, IEntityClass> ();
- }
- public IEntityClass createTestEntityClass(String name) {
- return new TestEntityClass(name);
- }
-
- public void addSwitchEntity(Long dpid, IEntityClass entityClass) {
- switchEntities.put(dpid, entityClass);
- }
- public void removeSwitchEntity(Long dpid) {
- switchEntities.remove(dpid);
- }
- public void addVlanEntities(Short vlan, IEntityClass entityClass) {
- vlanEntities.put(vlan, entityClass);
- }
- public void removeVlanEntities(Short vlan) {
- vlanEntities.remove(vlan);
- }
- @Override
- public IEntityClass classifyEntity(Entity entity) {
- if (switchEntities.containsKey(entity.getSwitchDPID()))
- return switchEntities.get(entity.getSwitchDPID());
- if (vlanEntities.containsKey(entity.getVlan()))
- return vlanEntities.get(entity.getVlan());
- return defaultClass;
- }
- @Override
- public EnumSet<IDeviceService.DeviceField> getKeyFields() {
- return EnumSet.of(MAC, VLAN, SWITCH, PORT);
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
deleted file mode 100644
index f29c319..0000000
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ /dev/null
@@ -1,518 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.forwarding;
-
-import static org.easymock.EasyMock.anyLong;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.anyShort;
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-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.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClassifierService;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
-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.routing.IRoutingService;
-import net.floodlightcontroller.routing.Route;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.ITopologyListener;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.topology.NodePortTuple;
-
-import org.easymock.Capture;
-import org.easymock.CaptureType;
-import org.easymock.EasyMock;
-import org.junit.Test;
-import org.openflow.protocol.OFFeaturesReply;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-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;
- protected Forwarding forwarding;
- protected ITopologyService topology;
- protected MockThreadPoolService threadPool;
- protected IOFSwitch sw1, sw2;
- protected OFFeaturesReply swFeatures;
- protected IDevice srcDevice, dstDevice1, dstDevice2;
- protected OFPacketIn packetIn;
- protected OFPacketOut packetOut;
- protected OFPacketOut packetOutFlooded;
- protected IPacket testPacket;
- protected byte[] testPacketSerialized;
- protected int expected_wildcards;
- protected Date currentDate;
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
- cntx = new FloodlightContext();
-
- // Module loader setup
- /*
- Collection<Class<? extends IFloodlightModule>> mods = new ArrayList<Class<? extends IFloodlightModule>>();
- Collection<IFloodlightService> mockedServices = new ArrayList<IFloodlightService>();
- mods.add(Forwarding.class);
- routingEngine = createMock(IRoutingService.class);
- topology = createMock(ITopologyService.class);
- mockedServices.add(routingEngine);
- mockedServices.add(topology);
- FloodlightTestModuleLoader fml = new FloodlightTestModuleLoader();
- fml.setupModules(mods, mockedServices);
- mockFloodlightProvider =
- (MockFloodlightProvider) fml.getModuleByName(MockFloodlightProvider.class);
- deviceManager =
- (MockDeviceManager) fml.getModuleByName(MockDeviceManager.class);
- threadPool =
- (MockThreadPoolService) fml.getModuleByName(MockThreadPoolService.class);
- forwarding =
- (Forwarding) fml.getModuleByName(Forwarding.class);
- */
- mockFloodlightProvider = getMockFloodlightProvider();
- forwarding = new Forwarding();
- threadPool = new MockThreadPoolService();
- deviceManager = new MockDeviceManager();
- routingEngine = createMock(IRoutingService.class);
- topology = createMock(ITopologyService.class);
- DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
-
-
- FloodlightModuleContext fmc = new FloodlightModuleContext();
- fmc.addService(IFloodlightProviderService.class,
- mockFloodlightProvider);
- fmc.addService(IThreadPoolService.class, threadPool);
- fmc.addService(ITopologyService.class, topology);
- fmc.addService(IRoutingService.class, routingEngine);
- fmc.addService(IDeviceService.class, deviceManager);
- fmc.addService(IEntityClassifierService.class, entityClassifier);
-
- topology.addListener(anyObject(ITopologyListener.class));
- expectLastCall().anyTimes();
- replay(topology);
- threadPool.init(fmc);
- forwarding.init(fmc);
- deviceManager.init(fmc);
- entityClassifier.init(fmc);
- threadPool.startUp(fmc);
- deviceManager.startUp(fmc);
- forwarding.startUp(fmc);
- entityClassifier.startUp(fmc);
- verify(topology);
-
- swFeatures = new OFFeaturesReply();
- swFeatures.setBuffers(1000);
- // Mock switches
- sw1 = EasyMock.createMock(IOFSwitch.class);
- expect(sw1.getId()).andReturn(1L).anyTimes();
- expect(sw1.getBuffers()).andReturn(swFeatures.getBuffers()).anyTimes();
- expect(sw1.getStringId())
- .andReturn(HexString.toHexString(1L)).anyTimes();
-
- sw2 = EasyMock.createMock(IOFSwitch.class);
- expect(sw2.getId()).andReturn(2L).anyTimes();
- expect(sw2.getBuffers()).andReturn(swFeatures.getBuffers()).anyTimes();
- expect(sw2.getStringId())
- .andReturn(HexString.toHexString(2L)).anyTimes();
-
- //fastWilcards mocked as this constant
- int fastWildcards =
- OFMatch.OFPFW_IN_PORT |
- OFMatch.OFPFW_NW_PROTO |
- OFMatch.OFPFW_TP_SRC |
- OFMatch.OFPFW_TP_DST |
- OFMatch.OFPFW_NW_SRC_ALL |
- OFMatch.OFPFW_NW_DST_ALL |
- OFMatch.OFPFW_NW_TOS;
-
- expect(sw1.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer)fastWildcards).anyTimes();
- expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
-
- expect(sw2.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer)fastWildcards).anyTimes();
- expect(sw2.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
-
- // Load the switch map
- Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
- switches.put(1L, sw1);
- switches.put(2L, sw2);
- mockFloodlightProvider.setSwitches(switches);
-
- // Build test packet
- testPacket = new Ethernet()
- .setDestinationMACAddress("00:11:22:33:44:55")
- .setSourceMACAddress("00:44:33:22:11:00")
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.1.2")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
-
-
-
- currentDate = new Date();
-
- // Mock Packet-in
- testPacketSerialized = testPacket.serialize();
- packetIn =
- ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(testPacketSerialized)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) testPacketSerialized.length);
-
- // Mock Packet-out
- packetOut =
- (OFPacketOut) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.PACKET_OUT);
- packetOut.setBufferId(this.packetIn.getBufferId())
- .setInPort(this.packetIn.getInPort());
- List<OFAction> poactions = new ArrayList<OFAction>();
- poactions.add(new OFActionOutput((short) 3, (short) 0xffff));
- packetOut.setActions(poactions)
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
- .setPacketData(testPacketSerialized)
- .setLengthU(OFPacketOut.MINIMUM_LENGTH+
- packetOut.getActionsLength()+
- testPacketSerialized.length);
-
- // Mock Packet-out with OFPP_FLOOD action
- packetOutFlooded =
- (OFPacketOut) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.PACKET_OUT);
- packetOutFlooded.setBufferId(this.packetIn.getBufferId())
- .setInPort(this.packetIn.getInPort());
- poactions = new ArrayList<OFAction>();
- poactions.add(new OFActionOutput(OFPort.OFPP_FLOOD.getValue(),
- (short) 0xffff));
- packetOutFlooded.setActions(poactions)
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
- .setPacketData(testPacketSerialized)
- .setLengthU(OFPacketOut.MINIMUM_LENGTH+
- packetOutFlooded.getActionsLength()+
- testPacketSerialized.length);
-
- expected_wildcards = fastWildcards;
- expected_wildcards &= ~OFMatch.OFPFW_IN_PORT &
- ~OFMatch.OFPFW_DL_VLAN &
- ~OFMatch.OFPFW_DL_SRC &
- ~OFMatch.OFPFW_DL_DST;
- expected_wildcards &= ~OFMatch.OFPFW_NW_SRC_MASK &
- ~OFMatch.OFPFW_NW_DST_MASK;
-
- IFloodlightProviderService.bcStore.
- put(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
- (Ethernet)testPacket);
- }
-
- enum DestDeviceToLearn { NONE, DEVICE1 ,DEVICE2 };
- public void learnDevices(DestDeviceToLearn destDeviceToLearn) {
- // Build src and dest devices
- byte[] dataLayerSource = ((Ethernet)testPacket).getSourceMACAddress();
- byte[] dataLayerDest =
- ((Ethernet)testPacket).getDestinationMACAddress();
- int networkSource =
- ((IPv4)((Ethernet)testPacket).getPayload()).
- getSourceAddress();
- int networkDest =
- ((IPv4)((Ethernet)testPacket).getPayload()).
- getDestinationAddress();
-
- reset(topology);
- expect(topology.isAttachmentPointPort(1L, (short)1))
- .andReturn(true)
- .anyTimes();
- expect(topology.isAttachmentPointPort(2L, (short)3))
- .andReturn(true)
- .anyTimes();
- expect(topology.isAttachmentPointPort(1L, (short)3))
- .andReturn(true)
- .anyTimes();
- replay(topology);
-
- srcDevice =
- deviceManager.learnEntity(Ethernet.toLong(dataLayerSource),
- null, networkSource,
- 1L, 1);
- IDeviceService.fcStore. put(cntx,
- IDeviceService.CONTEXT_SRC_DEVICE,
- srcDevice);
- if (destDeviceToLearn == DestDeviceToLearn.DEVICE1) {
- dstDevice1 =
- deviceManager.learnEntity(Ethernet.toLong(dataLayerDest),
- null, networkDest,
- 2L, 3);
- IDeviceService.fcStore.put(cntx,
- IDeviceService.CONTEXT_DST_DEVICE,
- dstDevice1);
- }
- if (destDeviceToLearn == DestDeviceToLearn.DEVICE2) {
- dstDevice2 =
- deviceManager.learnEntity(Ethernet.toLong(dataLayerDest),
- null, networkDest,
- 1L, 3);
- IDeviceService.fcStore.put(cntx,
- IDeviceService.CONTEXT_DST_DEVICE,
- dstDevice2);
- }
- verify(topology);
- }
-
- @Test
- public void testForwardMultiSwitchPath() throws Exception {
- learnDevices(DestDeviceToLearn.DEVICE1);
-
- Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
- Capture<OFMessage> wc2 = new Capture<OFMessage>(CaptureType.ALL);
- Capture<FloodlightContext> bc1 =
- new Capture<FloodlightContext>(CaptureType.ALL);
- Capture<FloodlightContext> bc2 =
- new Capture<FloodlightContext>(CaptureType.ALL);
-
-
- Route route = new Route(1L, 2L);
- List<NodePortTuple> nptList = new ArrayList<NodePortTuple>();
- nptList.add(new NodePortTuple(1L, (short)1));
- nptList.add(new NodePortTuple(1L, (short)3));
- nptList.add(new NodePortTuple(2L, (short)1));
- nptList.add(new NodePortTuple(2L, (short)3));
- route.setPath(nptList);
- expect(routingEngine.getRoute(1L, (short)1, 2L, (short)3)).andReturn(route).atLeastOnce();
-
- // Expected Flow-mods
- OFMatch match = new OFMatch();
- match.loadFromPacket(testPacketSerialized, (short) 1);
- OFActionOutput action = new OFActionOutput((short)3, (short)0xffff);
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(action);
-
- OFFlowMod fm1 =
- (OFFlowMod) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.FLOW_MOD);
- fm1.setIdleTimeout((short)5)
- .setMatch(match.clone()
- .setWildcards(expected_wildcards))
- .setActions(actions)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setCookie(2L << 52)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
- OFFlowMod fm2 = fm1.clone();
- ((OFActionOutput)fm2.getActions().get(0)).setPort((short) 3);
-
- sw1.write(capture(wc1), capture(bc1));
- expectLastCall().anyTimes();
- sw2.write(capture(wc2), capture(bc2));
- expectLastCall().anyTimes();
-
- reset(topology);
- expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
- expect(topology.getL2DomainId(2L)).andReturn(1L).anyTimes();
- expect(topology.isAttachmentPointPort(1L, (short)1)).andReturn(true).anyTimes();
- expect(topology.isAttachmentPointPort(2L, (short)3)).andReturn(true).anyTimes();
- expect(topology.isIncomingBroadcastAllowed(anyLong(), anyShort())).andReturn(true).anyTimes();
-
- // Reset mocks, trigger the packet in, and validate results
- replay(sw1, sw2, routingEngine, topology);
- forwarding.receive(sw1, this.packetIn, cntx);
- verify(sw1, sw2, routingEngine);
-
- assertTrue(wc1.hasCaptured()); // wc1 should get packetout + flowmod.
- assertTrue(wc2.hasCaptured()); // wc2 should be a flowmod.
-
- List<OFMessage> msglist = wc1.getValues();
-
- for (OFMessage m: msglist) {
- if (m instanceof OFFlowMod)
- assertEquals(fm1, m);
- else if (m instanceof OFPacketOut)
- assertEquals(packetOut, m);
- }
-
- OFMessage m = wc2.getValue();
- assert (m instanceof OFFlowMod);
- assertTrue(m.equals(fm2));
- }
-
- @Test
- public void testForwardSingleSwitchPath() throws Exception {
- learnDevices(DestDeviceToLearn.DEVICE2);
-
- Route route = new Route(1L, 1L);
- route.getPath().add(new NodePortTuple(1L, (short)1));
- route.getPath().add(new NodePortTuple(1L, (short)3));
- expect(routingEngine.getRoute(1L, (short)1, 1L, (short)3)).andReturn(route).atLeastOnce();
-
- // Expected Flow-mods
- OFMatch match = new OFMatch();
- match.loadFromPacket(testPacketSerialized, (short) 1);
- OFActionOutput action = new OFActionOutput((short)3, (short)0xffff);
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(action);
-
- OFFlowMod fm1 =
- (OFFlowMod) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.FLOW_MOD);
- fm1.setIdleTimeout((short)5)
- .setMatch(match.clone()
- .setWildcards(expected_wildcards))
- .setActions(actions)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setCookie(2L << 52)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH +
- OFActionOutput.MINIMUM_LENGTH);
-
- // Record expected packet-outs/flow-mods
- sw1.write(fm1, cntx);
- sw1.write(packetOut, cntx);
-
- reset(topology);
- expect(topology.isIncomingBroadcastAllowed(anyLong(), anyShort())).andReturn(true).anyTimes();
- expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
- expect(topology.isAttachmentPointPort(1L, (short)1)).andReturn(true).anyTimes();
- expect(topology.isAttachmentPointPort(1L, (short)3)).andReturn(true).anyTimes();
-
- // Reset mocks, trigger the packet in, and validate results
- replay(sw1, sw2, routingEngine, topology);
- forwarding.receive(sw1, this.packetIn, cntx);
- verify(sw1, sw2, routingEngine);
- }
-
- @Test
- public void testFlowModDampening() throws Exception {
- learnDevices(DestDeviceToLearn.DEVICE2);
-
- reset(topology);
- expect(topology.isAttachmentPointPort(EasyMock.anyLong(), EasyMock.anyShort()))
- .andReturn(true).anyTimes();
- expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
- replay(topology);
-
-
- Route route = new Route(1L, 1L);
- route.getPath().add(new NodePortTuple(1L, (short)1));
- route.getPath().add(new NodePortTuple(1L, (short)3));
- expect(routingEngine.getRoute(1L, (short)1, 1L, (short)3)).andReturn(route).atLeastOnce();
-
- // Expected Flow-mods
- OFMatch match = new OFMatch();
- match.loadFromPacket(testPacketSerialized, (short) 1);
- OFActionOutput action = new OFActionOutput((short)3, (short)0xffff);
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(action);
-
- OFFlowMod fm1 =
- (OFFlowMod) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.FLOW_MOD);
- fm1.setIdleTimeout((short)5)
- .setMatch(match.clone()
- .setWildcards(expected_wildcards))
- .setActions(actions)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setCookie(2L << 52)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH +
- OFActionOutput.MINIMUM_LENGTH);
-
- // Record expected packet-outs/flow-mods
- // We will inject the packet_in 3 times and expect 1 flow mod and
- // 3 packet outs due to flow mod dampening
- sw1.write(fm1, cntx);
- expectLastCall().once();
- sw1.write(packetOut, cntx);
- expectLastCall().times(3);
-
- reset(topology);
- expect(topology.isIncomingBroadcastAllowed(anyLong(), anyShort())).andReturn(true).anyTimes();
- expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
- expect(topology.isAttachmentPointPort(1L, (short)1)).andReturn(true).anyTimes();
- expect(topology.isAttachmentPointPort(1L, (short)3)).andReturn(true).anyTimes();
-
- // Reset mocks, trigger the packet in, and validate results
- replay(sw1, routingEngine, topology);
- forwarding.receive(sw1, this.packetIn, cntx);
- forwarding.receive(sw1, this.packetIn, cntx);
- forwarding.receive(sw1, this.packetIn, cntx);
- verify(sw1, routingEngine);
- }
-
- @Test
- public void testForwardNoPath() throws Exception {
- learnDevices(DestDeviceToLearn.NONE);
-
- // Set no destination attachment point or route
- // expect no Flow-mod but expect the packet to be flooded
-
- // Reset mocks, trigger the packet in, and validate results
- reset(topology);
- expect(topology.isIncomingBroadcastAllowed(1L, (short)1)).andReturn(true).anyTimes();
- expect(topology.isAttachmentPointPort(EasyMock.anyLong(),
- EasyMock.anyShort()))
- .andReturn(true)
- .anyTimes();
- expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD))
- .andReturn(true).anyTimes();
- sw1.write(packetOutFlooded, cntx);
- expectLastCall().once();
- replay(sw1, sw2, routingEngine, topology);
- forwarding.receive(sw1, this.packetIn, cntx);
- verify(sw1, sw2, routingEngine);
- }
-
-}
diff --git a/src/test/java/net/floodlightcontroller/routing/RouteTest.java b/src/test/java/net/floodlightcontroller/routing/RouteTest.java
deleted file mode 100644
index 3bd0398..0000000
--- a/src/test/java/net/floodlightcontroller/routing/RouteTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-* License for the specific language governing permissions and limitations
-* under the License.
-**/
-
-package net.floodlightcontroller.routing;
-
-import org.junit.Test;
-
-import net.floodlightcontroller.routing.Route;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.topology.NodePortTuple;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class RouteTest extends FloodlightTestCase {
- @Test
- public void testCloneable() throws Exception {
- Route r1 = new Route(1L, 2L);
- Route r2 = new Route(1L, 3L);
-
- assertNotSame(r1, r2);
- assertNotSame(r1.getId(), r2.getId());
-
- r1 = new Route(1L, 3L);
- r1.getPath().add(new NodePortTuple(1L, (short)1));
- r1.getPath().add(new NodePortTuple(2L, (short)1));
- r1.getPath().add(new NodePortTuple(2L, (short)2));
- r1.getPath().add(new NodePortTuple(3L, (short)1));
-
- r2.getPath().add(new NodePortTuple(1L, (short)1));
- r2.getPath().add(new NodePortTuple(2L, (short)1));
- r2.getPath().add(new NodePortTuple(2L, (short)2));
- r2.getPath().add(new NodePortTuple(3L, (short)1));
-
- assertEquals(r1, r2);
-
- NodePortTuple temp = r2.getPath().remove(0);
- assertNotSame(r1, r2);
-
- r2.getPath().add(0, temp);
- assertEquals(r1, r2);
-
- r2.getPath().remove(1);
- temp = new NodePortTuple(2L, (short)5);
- r2.getPath().add(1, temp);
- assertNotSame(r1, r2);
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
index b0e83cc..f96d374 100644
--- a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
+++ b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
@@ -18,17 +18,9 @@
package net.floodlightcontroller.test;
import junit.framework.TestCase;
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.packet.Ethernet;
import org.junit.Test;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
/**
* This class gets a handle on the application context which is used to
@@ -46,42 +38,6 @@
public void setMockFloodlightProvider(MockFloodlightProvider mockFloodlightProvider) {
this.mockFloodlightProvider = mockFloodlightProvider;
}
-
- public FloodlightContext parseAndAnnotate(OFMessage m,
- IDevice srcDevice,
- IDevice dstDevice) {
- FloodlightContext bc = new FloodlightContext();
- return parseAndAnnotate(bc, m, srcDevice, dstDevice);
- }
-
- public FloodlightContext parseAndAnnotate(OFMessage m) {
- return parseAndAnnotate(m, null, null);
- }
-
- public FloodlightContext parseAndAnnotate(FloodlightContext bc,
- OFMessage m,
- IDevice srcDevice,
- IDevice dstDevice) {
- if (OFType.PACKET_IN.equals(m.getType())) {
- OFPacketIn pi = (OFPacketIn)m;
- Ethernet eth = new Ethernet();
- eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
- IFloodlightProviderService.bcStore.put(bc,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
- eth);
- }
- if (srcDevice != null) {
- IDeviceService.fcStore.put(bc,
- IDeviceService.CONTEXT_SRC_DEVICE,
- srcDevice);
- }
- if (dstDevice != null) {
- IDeviceService.fcStore.put(bc,
- IDeviceService.CONTEXT_DST_DEVICE,
- dstDevice);
- }
- return bc;
- }
@Override
public void setUp() throws Exception {
diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
deleted file mode 100644
index 8653625..0000000
--- a/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
+++ /dev/null
@@ -1,518 +0,0 @@
-package net.floodlightcontroller.topology;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import static org.junit.Assert.*;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.NodePortTuple;
-import net.floodlightcontroller.topology.TopologyInstance;
-import net.floodlightcontroller.topology.TopologyManager;
-import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopologyInstanceTest {
- protected final static Logger log = LoggerFactory.getLogger(TopologyInstanceTest.class);
- protected TopologyManager topologyManager;
- protected FloodlightModuleContext fmc;
- protected MockFloodlightProvider mockFloodlightProvider;
-
- protected int DIRECT_LINK = 1;
- protected int MULTIHOP_LINK = 2;
- protected int TUNNEL_LINK = 3;
-
- @Before
- public void SetUp() throws Exception {
- fmc = new FloodlightModuleContext();
- mockFloodlightProvider = new MockFloodlightProvider();
- fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider);
- MockThreadPoolService tp = new MockThreadPoolService();
- topologyManager = new TopologyManager();
- fmc.addService(IThreadPoolService.class, tp);
- topologyManager.init(fmc);
- tp.init(fmc);
- tp.startUp(fmc);
- }
-
- protected void verifyClusters(int[][] clusters) {
- verifyClusters(clusters, true);
- }
-
- protected void verifyClusters(int[][] clusters, boolean tunnelsEnabled) {
- List<Long> verifiedSwitches = new ArrayList<Long>();
-
- // Make sure the expected cluster arrays are sorted so we can
- // use binarySearch to test for membership
- for (int i = 0; i < clusters.length; i++)
- Arrays.sort(clusters[i]);
-
- TopologyInstance ti =
- topologyManager.getCurrentInstance(tunnelsEnabled);
- Set<Long> switches = ti.getSwitches();
-
- for (long sw: switches) {
- if (!verifiedSwitches.contains(sw)) {
-
- int[] expectedCluster = null;
-
- for (int j = 0; j < clusters.length; j++) {
- if (Arrays.binarySearch(clusters[j], (int) sw) >= 0) {
- expectedCluster = clusters[j];
- break;
- }
- }
- if (expectedCluster != null) {
- Set<Long> cluster = ti.getSwitchesInOpenflowDomain(sw);
- assertEquals(expectedCluster.length, cluster.size());
- for (long sw2: cluster) {
- assertTrue(Arrays.binarySearch(expectedCluster, (int)sw2) >= 0);
- verifiedSwitches.add(sw2);
- }
- }
- }
- }
- }
-
- protected void
- verifyExpectedBroadcastPortsInClusters(int [][][] ebp) {
- verifyExpectedBroadcastPortsInClusters(ebp, true);
- }
-
- protected void
- verifyExpectedBroadcastPortsInClusters(int [][][] ebp,
- boolean tunnelsEnabled) {
- NodePortTuple npt = null;
- Set<NodePortTuple> expected = new HashSet<NodePortTuple>();
- for(int i=0; i<ebp.length; ++i) {
- int [][] nptList = ebp[i];
- expected.clear();
- for(int j=0; j<nptList.length; ++j) {
- npt = new NodePortTuple((long)nptList[j][0], (short)nptList[j][1]);
- expected.add(npt);
- }
- TopologyInstance ti = topologyManager.getCurrentInstance(tunnelsEnabled);
- Set<NodePortTuple> computed = ti.getBroadcastNodePortsInCluster(npt.nodeId);
- if (computed != null)
- assertTrue(computed.equals(expected));
- else if (computed == null)
- assertTrue(expected.isEmpty());
- }
- }
-
- public void createTopologyFromLinks(int [][] linkArray) throws Exception {
- ILinkDiscovery.LinkType type = ILinkDiscovery.LinkType.DIRECT_LINK;
-
- // Use topologymanager to write this test, it will make it a lot easier.
- for (int i = 0; i < linkArray.length; i++) {
- int [] r = linkArray[i];
- if (r[4] == DIRECT_LINK)
- type= ILinkDiscovery.LinkType.DIRECT_LINK;
- else if (r[4] == MULTIHOP_LINK)
- type= ILinkDiscovery.LinkType.MULTIHOP_LINK;
- else if (r[4] == TUNNEL_LINK)
- type = ILinkDiscovery.LinkType.TUNNEL;
-
- topologyManager.addOrUpdateLink((long)r[0], (short)r[1], (long)r[2], (short)r[3], type);
- }
- topologyManager.createNewInstance();
- }
-
- public TopologyManager getTopologyManager() {
- return topologyManager;
- }
-
- @Test
- public void testClusters() throws Exception {
- TopologyManager tm = getTopologyManager();
- {
- int [][] linkArray = {
- {1, 1, 2, 1, DIRECT_LINK},
- {2, 2, 3, 2, DIRECT_LINK},
- {3, 1, 1, 2, DIRECT_LINK},
- {2, 3, 4, 2, DIRECT_LINK},
- {3, 3, 4, 1, DIRECT_LINK}
- };
- int [][] expectedClusters = {
- {1,2,3},
- {4}
- };
- //tm.recompute();
- createTopologyFromLinks(linkArray);
- verifyClusters(expectedClusters);
- }
-
- {
- int [][] linkArray = {
- {5, 3, 6, 1, DIRECT_LINK}
- };
- int [][] expectedClusters = {
- {1,2,3},
- {4},
- {5},
- {6}
- };
- createTopologyFromLinks(linkArray);
-
- verifyClusters(expectedClusters);
- }
-
- {
- int [][] linkArray = {
- {6, 1, 5, 3, DIRECT_LINK}
- };
- int [][] expectedClusters = {
- {1,2,3},
- {4},
- {5,6}
- };
- createTopologyFromLinks(linkArray);
-
- verifyClusters(expectedClusters);
- }
-
- {
- int [][] linkArray = {
- {4, 2, 2, 3, DIRECT_LINK}
- };
- int [][] expectedClusters = {
- {1,2,3,4},
- {5,6}
- };
- createTopologyFromLinks(linkArray);
-
- verifyClusters(expectedClusters);
- }
- {
- int [][] linkArray = {
- {4, 3, 5, 1, DIRECT_LINK}
- };
- int [][] expectedClusters = {
- {1,2,3,4},
- {5,6}
- };
- createTopologyFromLinks(linkArray);
-
- verifyClusters(expectedClusters);
- }
- {
- int [][] linkArray = {
- {5, 2, 2, 4, DIRECT_LINK}
- };
- int [][] expectedClusters = {
- {1,2,3,4,5,6}
- };
- createTopologyFromLinks(linkArray);
-
- verifyClusters(expectedClusters);
- }
-
- //Test 2.
- {
- int [][] linkArray = {
- {3, 2, 2, 2, DIRECT_LINK},
- {2, 1, 1, 1, DIRECT_LINK},
- {1, 2, 3, 1, DIRECT_LINK},
- {4, 1, 3, 3, DIRECT_LINK},
- {5, 1, 4, 3, DIRECT_LINK},
- {2, 4, 5, 2, DIRECT_LINK}
- };
- int [][] expectedClusters = {
- {1,2,3,4,5,6}
- };
- createTopologyFromLinks(linkArray);
- verifyClusters(expectedClusters);
- }
-
- // Test 3. Remove links
- {
- tm.removeLink((long)5,(short)3,(long)6,(short)1);
- tm.removeLink((long)6,(short)1,(long)5,(short)3);
-
- int [][] expectedClusters = {
- {1,2,3,4,5},
- };
- topologyManager.createNewInstance();
- verifyClusters(expectedClusters);
- }
-
- // Remove Switch
- {
- tm.removeSwitch(4);
- int [][] expectedClusters = {
- {1,2,3,5},
- };
- topologyManager.createNewInstance();
- verifyClusters(expectedClusters);
- }
- }
-
- @Test
- public void testLoopDetectionInSingleIsland() throws Exception {
-
- int [][] linkArray = {
- {1, 1, 2, 1, DIRECT_LINK},
- {2, 1, 1, 1, DIRECT_LINK},
- {1, 2, 3, 1, DIRECT_LINK},
- {3, 1, 1, 2, DIRECT_LINK},
- {2, 2, 3, 2, DIRECT_LINK},
- {3, 2, 2, 2, DIRECT_LINK},
- {3, 3, 4, 1, DIRECT_LINK},
- {4, 1, 3, 3, DIRECT_LINK},
- {4, 2, 6, 2, DIRECT_LINK},
- {6, 2, 4, 2, DIRECT_LINK},
- {4, 3, 5, 1, DIRECT_LINK},
- {5, 1, 4, 3, DIRECT_LINK},
- {5, 2, 6, 1, DIRECT_LINK},
- {6, 1, 5, 2, DIRECT_LINK},
-
- };
- int [][] expectedClusters = {
- {1, 2, 3, 4, 5, 6}
- };
- int [][][] expectedBroadcastPorts = {
- {{1,1}, {2,1}, {1,2}, {3,1}, {3,3}, {4,1}, {4,3}, {5,1}, {4,2}, {6,2}},
- };
-
- createTopologyFromLinks(linkArray);
- topologyManager.createNewInstance();
- verifyClusters(expectedClusters);
- verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts);
- }
-
- @Test
- public void testTunnelLinkDeletion() throws Exception {
-
- // +-------+ +-------+
- // | | | |
- // | 1 1|-------------|1 2 |
- // | 2 | | 2 |
- // +-------+ +-------+
- // | |
- // | |
- // +-------+ |
- // | 1 | |
- // | 3 2|-----------------+
- // | 3 |
- // +-------+
- //
- //
- // +-------+
- // | 1 |
- // | 4 2|----------------+
- // | 3 | |
- // +-------+ |
- // | |
- // | |
- // +-------+ +-------+
- // | 1 | | 2 |
- // | 5 2|-------------|1 6 |
- // | | | |
- // +-------+ +-------+
- {
- int [][] linkArray = {
- {1, 1, 2, 1, DIRECT_LINK},
- {2, 1, 1, 1, DIRECT_LINK},
- {1, 2, 3, 1, TUNNEL_LINK},
- {3, 1, 1, 2, TUNNEL_LINK},
- {2, 2, 3, 2, TUNNEL_LINK},
- {3, 2, 2, 2, TUNNEL_LINK},
-
- {4, 2, 6, 2, DIRECT_LINK},
- {6, 2, 4, 2, DIRECT_LINK},
- {4, 3, 5, 1, TUNNEL_LINK},
- {5, 1, 4, 3, TUNNEL_LINK},
- {5, 2, 6, 1, TUNNEL_LINK},
- {6, 1, 5, 2, TUNNEL_LINK},
-
- };
-
- int [][] expectedClusters = {
- {1, 2},
- {4, 6},
- };
- int [][][] expectedBroadcastPorts = {
- {{1,1}, {2,1}},
- {{4,2}, {6,2}}
- };
-
- createTopologyFromLinks(linkArray);
- topologyManager.createNewInstance();
- verifyClusters(expectedClusters, false);
- verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts, false);
- }
-
- // +-------+ +-------+
- // | | TUNNEL | |
- // | 1 1|-------------|1 2 |
- // | 2 | | 2 |
- // +-------+ +-------+
- // | |
- // | |
- // +-------+ |
- // | 1 | |
- // | 3 2|-----------------+
- // | 3 |
- // +-------+
- // |
- // | TUNNEL
- // |
- // +-------+
- // | 1 | TUNNEL
- // | 4 2|----------------+
- // | 3 | |
- // +-------+ |
- // | |
- // | |
- // +-------+ +-------+
- // | 1 | | 2 |
- // | 5 2|-------------|1 6 |
- // | | | |
- // +-------+ +-------+
-
- {
- int [][] linkArray = {
- {3, 3, 4, 1, TUNNEL_LINK},
- {4, 1, 3, 3, TUNNEL_LINK},
-
- };
- int [][] expectedClusters = {
- {1, 2},
- {4, 6},
- {3},
- {5},
- };
- int [][][] expectedBroadcastPorts = {
- {{1,1}, {2,1}},
- {{4,2}, {6,2}}
- };
-
- createTopologyFromLinks(linkArray);
- topologyManager.createNewInstance();
- verifyClusters(expectedClusters, false);
- verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts, false);
- }
- }
-
- @Test
- public void testLoopDetectionWithIslands() throws Exception {
-
- // +-------+ +-------+
- // | | TUNNEL | |
- // | 1 1|-------------|1 2 |
- // | 2 | | 2 |
- // +-------+ +-------+
- // | |
- // | |
- // +-------+ |
- // | 1 | |
- // | 3 2|-----------------+
- // | 3 |
- // +-------+
- //
- //
- // +-------+
- // | 1 | TUNNEL
- // | 4 2|----------------+
- // | 3 | |
- // +-------+ |
- // | |
- // | |
- // +-------+ +-------+
- // | 1 | | 2 |
- // | 5 2|-------------|1 6 |
- // | | | |
- // +-------+ +-------+
- {
- int [][] linkArray = {
- {1, 1, 2, 1, TUNNEL_LINK},
- {2, 1, 1, 1, TUNNEL_LINK},
- {1, 2, 3, 1, DIRECT_LINK},
- {3, 1, 1, 2, DIRECT_LINK},
- {2, 2, 3, 2, DIRECT_LINK},
- {3, 2, 2, 2, DIRECT_LINK},
-
- {4, 2, 6, 2, TUNNEL_LINK},
- {6, 2, 4, 2, TUNNEL_LINK},
- {4, 3, 5, 1, DIRECT_LINK},
- {5, 1, 4, 3, DIRECT_LINK},
- {5, 2, 6, 1, DIRECT_LINK},
- {6, 1, 5, 2, DIRECT_LINK},
-
- };
-
- int [][] expectedClusters = {
- {1, 2, 3},
- {4, 5, 6}
- };
- int [][][] expectedBroadcastPorts = {
- {{1,2}, {3,1}, {2,2}, {3,2}},
- {{4,3}, {5,1}, {5,2}, {6,1}},
- };
-
- createTopologyFromLinks(linkArray);
- topologyManager.createNewInstance();
- verifyClusters(expectedClusters);
- verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts);
- }
-
- // +-------+ +-------+
- // | | TUNNEL | |
- // | 1 1|-------------|1 2 |
- // | 2 | | 2 |
- // +-------+ +-------+
- // | |
- // | |
- // +-------+ |
- // | 1 | |
- // | 3 2|-----------------+
- // | 3 |
- // +-------+
- // |
- // | TUNNEL
- // |
- // +-------+
- // | 1 | TUNNEL
- // | 4 2|----------------+
- // | 3 | |
- // +-------+ |
- // | |
- // | |
- // +-------+ +-------+
- // | 1 | | 2 |
- // | 5 2|-------------|1 6 |
- // | | | |
- // +-------+ +-------+
-
- {
- int [][] linkArray = {
- {3, 3, 4, 1, TUNNEL_LINK},
- {4, 1, 3, 3, TUNNEL_LINK},
-
- };
- int [][] expectedClusters = {
- {1, 2, 3},
- {4, 5, 6}
- };
- int [][][] expectedBroadcastPorts = {
- {{1,2}, {3,1}, {2,2}, {3,2}},
- {{4,3}, {5,1}, {5,2}, {6,1}},
- };
-
- createTopologyFromLinks(linkArray);
- topologyManager.createNewInstance();
- verifyClusters(expectedClusters, false);
- verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts);
- }
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
deleted file mode 100644
index 280c336..0000000
--- a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package net.floodlightcontroller.topology;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopologyManagerTest extends FloodlightTestCase {
- protected final static Logger log = LoggerFactory.getLogger(TopologyManagerTest.class);
- TopologyManager tm;
- FloodlightModuleContext fmc;
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
- fmc = new FloodlightModuleContext();
- fmc.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
- MockThreadPoolService tp = new MockThreadPoolService();
- fmc.addService(IThreadPoolService.class, tp);
- tm = new TopologyManager();
- tp.init(fmc);
- tm.init(fmc);
- tp.startUp(fmc);
- }
-
- @Test
- public void testBasic1() throws Exception {
- tm.addOrUpdateLink((long)1, (short)1, (long)2, (short)1, ILinkDiscovery.LinkType.DIRECT_LINK);
- assertTrue(tm.getSwitchPorts().size() == 2); // for two nodes.
- assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
- assertTrue(tm.getSwitchPortLinks().size()==2);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
- assertTrue(tm.getTunnelPorts().size()==0);
-
- tm.addOrUpdateLink((long)1, (short)2, (long)2, (short)2, ILinkDiscovery.LinkType.MULTIHOP_LINK);
- assertTrue(tm.getSwitchPorts().size() == 2); // for two nodes.
- assertTrue(tm.getSwitchPorts().get((long)1).size()==2);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==2);
- assertTrue(tm.getSwitchPortLinks().size()==4);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
- assertTrue(tm.getTunnelPorts().size()==0);
-
- tm.addOrUpdateLink((long)1, (short)3, (long)2, (short)3, ILinkDiscovery.LinkType.TUNNEL);
- assertTrue(tm.getSwitchPorts().size() == 2); // for two nodes.
- assertTrue(tm.getSwitchPorts().get((long)1).size()==3);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==3);
- assertTrue(tm.getSwitchPortLinks().size()==6);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
- assertTrue(tm.getTunnelPorts().size()==2);
-
- tm.removeLink((long)1, (short)2, (long)2, (short)2);
- log.info("# of switchports. {}", tm.getSwitchPorts().get((long)1).size());
- assertTrue(tm.getSwitchPorts().get((long)1).size()==2);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==2);
- assertTrue(tm.getSwitchPorts().size() == 2); // for two nodes.
- assertTrue(tm.getSwitchPortLinks().size()==4);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
- assertTrue(tm.getTunnelPorts().size()==2);
-
- tm.removeLink((long)1, (short)1, (long)2, (short)1);
- assertTrue(tm.getSwitchPorts().size() == 2); // for two nodes.
- assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
- assertTrue(tm.getSwitchPortLinks().size()==2);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
- assertTrue(tm.getTunnelPorts().size()==2);
-
- tm.removeLink((long)1, (short)3, (long)2, (short)3);
- assertTrue(tm.getSwitchPorts().size() == 0);
- assertTrue(tm.getSwitchPortLinks().size()==0);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
- assertTrue(tm.getTunnelPorts().size()==0);
- }
-
- @Test
- public void testBasic2() throws Exception {
- tm.addOrUpdateLink((long)1, (short)1, (long)2, (short)1, ILinkDiscovery.LinkType.DIRECT_LINK);
- tm.addOrUpdateLink((long)2, (short)2, (long)3, (short)1, ILinkDiscovery.LinkType.MULTIHOP_LINK);
- tm.addOrUpdateLink((long)3, (short)2, (long)1, (short)2, ILinkDiscovery.LinkType.TUNNEL);
- assertTrue(tm.getSwitchPorts().size() == 3); // for two nodes.
- assertTrue(tm.getSwitchPorts().get((long)1).size()==2);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==2);
- assertTrue(tm.getSwitchPorts().get((long)3).size()==2);
- assertTrue(tm.getSwitchPortLinks().size()==6);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
- assertTrue(tm.getTunnelPorts().size()==2);
-
- tm.removeLink((long)1, (short)1, (long)2, (short)1);
- assertTrue(tm.getSwitchPorts().size() == 3); // for two nodes.
- assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
- assertTrue(tm.getSwitchPorts().get((long)3).size()==2);
- assertTrue(tm.getSwitchPortLinks().size()==4);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
- assertTrue(tm.getTunnelPorts().size()==2);
-
- // nonexistent link // no null pointer exceptions.
- tm.removeLink((long)3, (short)1, (long)2, (short)2);
- assertTrue(tm.getSwitchPorts().size() == 3); // for two nodes.
- assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
- assertTrue(tm.getSwitchPorts().get((long)3).size()==2);
- assertTrue(tm.getSwitchPortLinks().size()==4);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
- assertTrue(tm.getTunnelPorts().size()==2);
-
- tm.removeLink((long)3, (short)2, (long)1, (short)2);
- assertTrue(tm.getSwitchPorts().size() == 2); // for two nodes.
- assertTrue(tm.getSwitchPorts().get((long)1)==null);
- assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
- assertTrue(tm.getSwitchPorts().get((long)3).size()==1);
- assertTrue(tm.getSwitchPortLinks().size()==2);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
- assertTrue(tm.getTunnelPorts().size()==0);
-
- tm.removeLink((long)2, (short)2, (long)3, (short)1);
- assertTrue(tm.getSwitchPorts().size() == 0); // for two nodes.
- assertTrue(tm.getSwitchPortLinks().size()==0);
- assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
- assertTrue(tm.getTunnelPorts().size()==0);
- }
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
index ecb87cf..c6d1143 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -33,16 +33,13 @@
import net.floodlightcontroller.core.test.MockThreadPoolService;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.routing.IRoutingService;
-import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.test.FloodlightTestCase;
import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.topology.NodePortTuple;
-import net.floodlightcontroller.topology.TopologyManager;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.Link;
import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+import net.onrc.onos.ofcontroller.linkdiscovery.NodePortTuple;
import org.junit.Before;
import org.junit.Test;
@@ -89,23 +86,18 @@
super.setUp();
FloodlightModuleContext cntx = new FloodlightModuleContext();
ldm = new TestLinkDiscoveryManager();
- TopologyManager routingEngine = new TopologyManager();
ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
MockThreadPoolService tp = new MockThreadPoolService();
RestApiServer restApi = new RestApiServer();
cntx.addService(IRestApiService.class, restApi);
cntx.addService(IThreadPoolService.class, tp);
- cntx.addService(IRoutingService.class, routingEngine);
cntx.addService(ILinkDiscoveryService.class, ldm);
- cntx.addService(ITopologyService.class, ldm);
cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
restApi.init(cntx);
tp.init(cntx);
- routingEngine.init(cntx);
ldm.init(cntx);
restApi.startUp(cntx);
tp.startUp(cntx);
- routingEngine.startUp(cntx);
ldm.startUp(cntx);
IOFSwitch sw1 = createMockSwitch(1L);