Merge branch 'master' of github.com:OPENNETWORKINGLAB/ONOS into RAMCloud-master
Conflicts:
pom.xml
src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
start-onos.sh
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudElement.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudElement.java
index 822bebe..f1183c5 100644
--- a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudElement.java
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudElement.java
@@ -26,9 +26,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.esotericsoftware.kryo2.Kryo;
-import com.esotericsoftware.kryo2.io.ByteBufferInput;
-import com.esotericsoftware.kryo2.io.Output;
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.ByteBufferInput;
+import com.esotericsoftware.kryo.io.Output;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Vertex;
diff --git a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
index 33091b9..5be4191 100644
--- a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
+++ b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
@@ -18,8 +18,10 @@
import net.floodlightcontroller.restserver.IRestApiService;
import net.onrc.onos.datagrid.web.DatagridWebRoutable;
import net.onrc.onos.ofcontroller.flowmanager.IFlowEventHandlerService;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
-import net.onrc.onos.ofcontroller.proxyarp.IArpEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
+import net.onrc.onos.ofcontroller.proxyarp.IArpReplyEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.IPacketOutEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.PacketOutNotification;
import net.onrc.onos.ofcontroller.topology.TopologyElement;
import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryId;
@@ -30,9 +32,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.esotericsoftware.kryo2.Kryo;
-import com.esotericsoftware.kryo2.io.Input;
-import com.esotericsoftware.kryo2.io.Output;
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
import com.hazelcast.config.Config;
import com.hazelcast.config.FileSystemXmlConfig;
import com.hazelcast.core.EntryEvent;
@@ -79,12 +81,18 @@
private MapTopologyListener mapTopologyListener = null;
private String mapTopologyListenerId = null;
- // State related to the ARP map
- protected static final String arpMapName = "arpMap";
- private IMap<ArpMessage, byte[]> arpMap = null;
- private List<IArpEventHandler> arpEventHandlers = new ArrayList<IArpEventHandler>();
+ // State related to the packet out map
+ protected static final String packetOutMapName = "packetOutMap";
+ private IMap<PacketOutNotification, byte[]> packetOutMap = null;
+ private List<IPacketOutEventHandler> packetOutEventHandlers = new ArrayList<IPacketOutEventHandler>();
+
private final byte[] dummyByte = {0};
+ // State related to the ARP reply map
+ protected static final String arpReplyMapName = "arpReplyMap";
+ private IMap<ArpReplyNotification, byte[]> arpReplyMap = null;
+ private List<IArpReplyEventHandler> arpReplyEventHandlers = new ArrayList<IArpReplyEventHandler>();
+
/**
* Class for receiving notifications for Flow state.
*
@@ -317,35 +325,23 @@
}
/**
- * Class for receiving notifications for ARP requests.
+ * Class for receiving notifications for sending packet-outs.
*
* The datagrid map is:
- * - Key: Request ID (String)
- * - Value: ARP request packet (byte[])
+ * - Key: Packet-out to send (PacketOutNotification)
+ * - Value: dummy value (we only need the key) (byte[])
*/
- class ArpMapListener implements EntryListener<ArpMessage, byte[]> {
+ class PacketOutMapListener implements EntryListener<PacketOutNotification, byte[]> {
/**
* Receive a notification that an entry is added.
*
* @param event the notification event for the entry.
*/
@Override
- public void entryAdded(EntryEvent<ArpMessage, byte[]> event) {
- for (IArpEventHandler arpEventHandler : arpEventHandlers) {
- arpEventHandler.arpRequestNotification(event.getKey());
+ public void entryAdded(EntryEvent<PacketOutNotification, byte[]> event) {
+ for (IPacketOutEventHandler packetOutEventHandler : packetOutEventHandlers) {
+ packetOutEventHandler.packetOutNotification(event.getKey());
}
-
- //
- // Decode the value and deliver the notification
- //
- /*
- Kryo kryo = kryoFactory.newKryo();
- Input input = new Input(valueBytes);
- TopologyElement topologyElement =
- kryo.readObject(input, TopologyElement.class);
- kryoFactory.deleteKryo(kryo);
- flowEventHandlerService.notificationRecvTopologyElementAdded(topologyElement);
- */
}
/**
@@ -354,7 +350,7 @@
* @param event the notification event for the entry.
*/
@Override
- public void entryRemoved(EntryEvent<ArpMessage, byte[]> event) {
+ public void entryRemoved(EntryEvent<PacketOutNotification, byte[]> event) {
// Not used
}
@@ -364,7 +360,7 @@
* @param event the notification event for the entry.
*/
@Override
- public void entryUpdated(EntryEvent<ArpMessage, byte[]> event) {
+ public void entryUpdated(EntryEvent<PacketOutNotification, byte[]> event) {
// Not used
}
@@ -374,12 +370,41 @@
* @param event the notification event for the entry.
*/
@Override
- public void entryEvicted(EntryEvent<ArpMessage, byte[]> event) {
+ public void entryEvicted(EntryEvent<PacketOutNotification, byte[]> event) {
// Not used
}
}
/**
+ * Class for receiving notifications for sending packet-outs.
+ *
+ * The datagrid map is:
+ * - Key: Packet-out to send (PacketOutNotification)
+ * - Value: dummy value (we only need the key) (byte[])
+ */
+ class ArpReplyMapListener implements EntryListener<ArpReplyNotification, byte[]> {
+ /**
+ * Receive a notification that an entry is added.
+ *
+ * @param event the notification event for the entry.
+ */
+ @Override
+ public void entryAdded(EntryEvent<ArpReplyNotification, byte[]> event) {
+ for (IArpReplyEventHandler arpReplyEventHandler : arpReplyEventHandlers) {
+ arpReplyEventHandler.arpReplyEvent(event.getKey());
+ }
+ }
+
+ // These methods aren't used for ARP replies
+ @Override
+ public void entryRemoved(EntryEvent<ArpReplyNotification, byte[]> event) {}
+ @Override
+ public void entryUpdated(EntryEvent<ArpReplyNotification, byte[]> event) {}
+ @Override
+ public void entryEvicted(EntryEvent<ArpReplyNotification, byte[]> event) {}
+ }
+
+ /**
* Initialize the Hazelcast Datagrid operation.
*
* @param conf the configuration filename.
@@ -495,8 +520,11 @@
restApi.addRestletRoutable(new DatagridWebRoutable());
- arpMap = hazelcastInstance.getMap(arpMapName);
- arpMap.addEntryListener(new ArpMapListener(), true);
+ packetOutMap = hazelcastInstance.getMap(packetOutMapName);
+ packetOutMap.addEntryListener(new PacketOutMapListener(), true);
+
+ arpReplyMap = hazelcastInstance.getMap(arpReplyMapName);
+ arpReplyMap.addEntryListener(new ArpReplyMapListener(), true);
}
/**
@@ -557,15 +585,27 @@
}
@Override
- public void registerArpEventHandler(IArpEventHandler arpEventHandler) {
- if (arpEventHandler != null) {
- arpEventHandlers.add(arpEventHandler);
+ public void registerPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler) {
+ if (packetOutEventHandler != null) {
+ packetOutEventHandlers.add(packetOutEventHandler);
}
}
@Override
- public void deregisterArpEventHandler(IArpEventHandler arpEventHandler) {
- arpEventHandlers.remove(arpEventHandler);
+ public void deregisterPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler) {
+ packetOutEventHandlers.remove(packetOutEventHandler);
+ }
+
+ @Override
+ public void registerArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler) {
+ if (arpReplyEventHandler != null) {
+ arpReplyEventHandlers.add(arpReplyEventHandler);
+ }
+ }
+
+ @Override
+ public void deregisterArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler) {
+ arpReplyEventHandlers.remove(arpReplyEventHandler);
}
/**
@@ -902,8 +942,12 @@
}
@Override
- public void sendArpRequest(ArpMessage arpMessage) {
- //log.debug("ARP bytes: {}", HexString.toHexString(arpRequest));
- arpMap.putAsync(arpMessage, dummyByte, 1L, TimeUnit.MILLISECONDS);
+ public void sendPacketOutNotification(PacketOutNotification packetOutNotification) {
+ packetOutMap.putAsync(packetOutNotification, dummyByte, 1L, TimeUnit.MILLISECONDS);
}
+
+ @Override
+ public void sendArpReplyNotification(ArpReplyNotification arpReply) {
+ arpReplyMap.putAsync(arpReply, dummyByte, 1L, TimeUnit.MILLISECONDS);
+ }
}
diff --git a/src/main/java/net/onrc/onos/datagrid/IDatagridService.java b/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
index 0f03d77..1478129 100644
--- a/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
+++ b/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
@@ -4,8 +4,10 @@
import net.floodlightcontroller.core.module.IFloodlightService;
import net.onrc.onos.ofcontroller.flowmanager.IFlowEventHandlerService;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
-import net.onrc.onos.ofcontroller.proxyarp.IArpEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
+import net.onrc.onos.ofcontroller.proxyarp.IArpReplyEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.IPacketOutEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.PacketOutNotification;
import net.onrc.onos.ofcontroller.topology.TopologyElement;
import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryId;
@@ -38,18 +40,32 @@
void deregisterFlowEventHandlerService(IFlowEventHandlerService flowEventHandlerService);
/**
- * Register event handler for ARP events.
+ * Register event handler for packet-out events.
*
- * @param arpEventHandler The ARP event handler to register.
+ * @param packetOutEventHandler The packet-out event handler to register.
*/
- public void registerArpEventHandler(IArpEventHandler arpEventHandler);
+ public void registerPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler);
/**
- * De-register event handler service for ARP events.
+ * Deregister event handler service for packet-out events.
*
- * @param arpEventHandler The ARP event handler to de-register.
+ * @param packetOutEventHandler The packet-out event handler to deregister.
*/
- public void deregisterArpEventHandler(IArpEventHandler arpEventHandler);
+ public void deregisterPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler);
+
+ /**
+ * Register event handler for ARP reply events.
+ *
+ * @param packetOutEventHandler The ARP reply event handler to register.
+ */
+ public void registerArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler);
+
+ /**
+ * Deregister event handler service for ARP reply events.
+ *
+ * @param packetOutEventHandler The ARP reply event handler to deregister.
+ */
+ public void deregisterArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler);
/**
* Get all Flows that are currently in the datagrid.
@@ -167,8 +183,21 @@
void notificationSendAllTopologyElementsRemoved();
/**
- * Send an ARP request to other ONOS instances
- * @param arpRequest The request packet to send
+ * Send a packet-out notification to other ONOS instances. This informs
+ * other instances that they should send this packet out some of the ports
+ * they control. Not all notifications are applicable to all instances
+ * (i.e. some notifications specify a single port to send the packet out),
+ * so each instance must determine whether it needs to take action when it
+ * receives the notification.
+ *
+ * @param packetOutNotification The packet notification to send
*/
- public void sendArpRequest(ArpMessage arpMessage);
+ public void sendPacketOutNotification(PacketOutNotification packetOutNotification);
+
+ /**
+ * Send notification to other ONOS instances that an ARP reply has been
+ * received.
+ * @param arpReply The notification of the ARP reply
+ */
+ public void sendArpReplyNotification(ArpReplyNotification arpReply);
}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
index 16869c5..b504c4b 100644
--- a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
@@ -11,6 +11,8 @@
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
import com.tinkerpop.frames.FramedGraph;
+import com.tinkerpop.frames.FramedGraphFactory;
+import com.tinkerpop.frames.modules.gremlingroovy.GremlinGroovyModule;
public class GraphDBConnection implements IDBConnection {
public enum Transaction {
@@ -33,6 +35,7 @@
.getLogger(GraphDBConnection.class);
private static GraphDBConnection singleton = new GraphDBConnection();
private static TitanGraph graph;
+ private static FramedGraphFactory factory;
private static FramedGraph<TitanGraph> fg;
private static EventTransactionalGraph<TitanGraph> eg;
private static String configFile;
@@ -86,7 +89,9 @@
graph.createKeyIndex("ipv4_address", Vertex.class);
}
graph.commit();
- fg = new FramedGraph<TitanGraph>(graph);
+ // Make sure you reuse the factory when creating new framed graphs
+ factory = new FramedGraphFactory(new GremlinGroovyModule());
+ fg = factory.create(graph);
eg = new EventTransactionalGraph<TitanGraph>(graph);
}
return singleton;
@@ -97,7 +102,12 @@
*/
@Override
public FramedGraph<TitanGraph> getFramedGraph() {
- return fg;
+ if (isValid()) {
+ return fg;
+ } else {
+ log.error("New FramedGraph failed");
+ return null;
+ }
}
/**
diff --git a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
index 80a6338..6a11eb2 100644
--- a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
+++ b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
@@ -1,5 +1,7 @@
package net.onrc.onos.graph;
+import java.util.Map;
+
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import org.slf4j.Logger;
@@ -9,8 +11,6 @@
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.blueprints.impls.ramcloud.*;
-import java.util.Map;
public class LocalTopologyEventListener implements LocalGraphChangedListener {
@@ -35,7 +35,8 @@
}
- public void edgeRemoved(Edge e) {
+ @Override
+ public void edgeRemoved(Edge e, Map<String, Object> arg1) {
// TODO Auto-generated method stub
// Fire NetMapEvents (LinkRemoved, FlowEntryRemoved, HostRemoved, PortRemoved)
TitanEdge edge = (TitanEdge) e;
@@ -72,7 +73,8 @@
}
- public void vertexRemoved(Vertex vertex) {
+ @Override
+ public void vertexRemoved(Vertex vertex, Map<String, Object> arg1) {
// TODO Auto-generated method stub
// Generate NetMapEvents
String type = (String) vertex.getProperty("type");
@@ -105,11 +107,6 @@
}
- public void vertexRemoved(Vertex vertex, Map<String, Object> props) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
- public void edgeRemoved(Edge edge, Map<String, Object> props) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
}
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 3ff6058..4f6c310 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -41,7 +41,6 @@
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.ofcontroller.proxyarp.BgpProxyArpManager;
import net.onrc.onos.ofcontroller.proxyarp.IArpRequester;
-import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
import net.onrc.onos.ofcontroller.topology.Topology;
import net.onrc.onos.ofcontroller.topology.TopologyManager;
@@ -78,8 +77,7 @@
public class BgpRoute implements IFloodlightModule, IBgpRouteService,
ITopologyListener, IArpRequester,
- IOFSwitchListener, IConfigInfoService,
- IProxyArpService {
+ IOFSwitchListener, IConfigInfoService {
private final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
@@ -1019,12 +1017,12 @@
}
OFMatch matchLLDP = new OFMatch();
- matchLLDP.setDataLayerType((short)0x8942);
+ matchLLDP.setDataLayerType((short)0x88cc);
matchLLDP.setWildcards(matchLLDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
fmLLDP.setMatch(matchLLDP);
OFMatch matchBDDP = new OFMatch();
- matchBDDP.setDataLayerType((short)0x88cc);
+ matchBDDP.setDataLayerType((short)0x8942);
matchBDDP.setWildcards(matchBDDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
fmBDDP.setMatch(matchBDDP);
@@ -1287,27 +1285,4 @@
public short getVlan() {
return vlan;
}
-
- /*
- * TODO This is a hack to get the REST API to work for ProxyArpManager.
- * The REST API is currently tied to the Floodlight module system and we
- * need to separate it to allow ONOS modules to use it. For now we will
- * proxy calls through to the ProxyArpManager (which is not a Floodlight
- * module) through this class which is a module.
- */
- @Override
- public MACAddress getMacAddress(InetAddress ipAddress) {
- return proxyArp.getMacAddress(ipAddress);
- }
-
- @Override
- public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
- boolean retry) {
- proxyArp.sendArpRequest(ipAddress, requester, retry);
- }
-
- @Override
- public List<String> getMappings() {
- return proxyArp.getMappings();
- }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java
index a9f2abe..9606d24 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java
@@ -35,7 +35,7 @@
log.warn("The content received from {} is not json", str);
}
- BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
+ BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String line;
while ((line = br.readLine()) != null) {
response.append(line);
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
index 8dd2f16..36729a6 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
@@ -40,7 +40,7 @@
public boolean deactivateSwitch(String dpid);
/*
* Update the port details
- */
+ */
public boolean updatePort(String dpid, short port, int state, String desc);
/*
* Associate a port on switch
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
index 6292150..6fcbb29 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
@@ -25,7 +25,6 @@
import com.thinkaurelius.titan.core.TitanException;
/**
* This is the class for storing the information of devices into CassandraDB
- *
* @author Pankaj
*/
public class DeviceStorageImpl implements IDeviceStorage {
@@ -41,7 +40,7 @@
try {
ope = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
} catch (Exception e) {
- log.error(e.getMessage());
+ log.error("Couldn't open graph operation", e);
}
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
index d6bba8c..3a6db70 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
@@ -78,7 +78,7 @@
}
- private class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
+ private static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
@Override
public Link compute(PathPipe<Vertex> pipe) {
long s_dpid = 0;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
index 6c2e1d0..4d564e9 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -20,6 +20,7 @@
import net.floodlightcontroller.devicemanager.IDeviceListener;
import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.graph.DBOperation;
import net.onrc.onos.graph.DBConnection;
import net.onrc.onos.graph.GraphDBManager;
@@ -38,7 +39,7 @@
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.ArpMessage;
+import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
import net.onrc.onos.ofcontroller.topology.TopologyElement;
import net.onrc.onos.registry.controller.IControllerRegistryService;
import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
@@ -65,7 +66,7 @@
//protected IDeviceService deviceService;
protected IControllerRegistryService registryService;
protected DBOperation op;
-
+
protected static final String DBConfigFile = "dbconf";
protected static final String GraphDBStore = "graph_db_store";
protected static final String CleanupEnabled = "EnableCleanup";
@@ -387,8 +388,9 @@
log.debug("{}:deviceAdded(): Adding device {}",this.getClass(),device.getMACAddressString());
devStore.addDevice(device);
for (int intIpv4Address : device.getIPv4Addresses()) {
- datagridService.sendArpRequest(
- ArpMessage.newReply(InetAddresses.fromInteger(intIpv4Address)));
+ datagridService.sendArpReplyNotification(new ArpReplyNotification(
+ InetAddresses.fromInteger(intIpv4Address),
+ MACAddress.valueOf(device.getMACAddress())));
}
}
@@ -453,7 +455,7 @@
if (op == null) {
System.out.println("publisher op is null");
}
-
+
floodlightProvider =
context.getServiceImpl(IFloodlightProviderService.class);
//deviceService = context.getServiceImpl(IDeviceService.class);
@@ -464,13 +466,13 @@
devStore = new DeviceStorageImpl();
devStore.init(dbStore, conf);
-
+
swStore = new SwitchStorageImpl();
swStore.init(dbStore, conf);
-
+
linkStore = new LinkStorageImpl();
linkStore.init(dbStore, conf);
-
+
log.debug("Initializing NetworkGraphPublisher module with {}", conf);
}
@@ -487,7 +489,7 @@
log.debug("Adding EventListener");
IDBConnection conn = op.getDBConnection();
conn.addEventListener(new LocalTopologyEventListener((DBConnection) conn));
- // Setup the Cleanup task.
+ // Setup the Cleanup task.
if (cleanupNeeded == null || !cleanupNeeded.equals("False")) {
ScheduledExecutorService ses = threadPool.getScheduledExecutor();
cleanupTask = new SingletonTask(ses, new SwitchCleanup());
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
index 343b532..e3dcad0 100755
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -677,8 +677,10 @@
for (IFlowPath flowPathObj : allFlowPaths) {
if (flowPathObj == null)
continue;
+
deleteIFlowPath(dbHandler, flowPathObj);
}
+ dbHandler.commit();
return true;
}
@@ -706,10 +708,16 @@
}
deleteIFlowPath(dbHandler, flowObj);
-
+ dbHandler.commit();
return true;
}
+ /**
+ * Delete a previously added flow.
+ * @note You need to call commit after calling this method.
+ * @param dbHandler the Graph Database handler to use.
+ * @param flowObj IFlowPath object to delete.
+ */
private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
//
// Remove all Flow Entries
@@ -721,7 +729,6 @@
}
// Remove the Flow itself
dbHandler.removeFlowPath(flowObj);
- dbHandler.commit();
}
/**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
index 001fb3c..67a2ad1 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -33,7 +33,7 @@
import net.onrc.onos.ofcontroller.util.FlowPathUserState;
import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
-import com.esotericsoftware.kryo2.Kryo;
+import com.esotericsoftware.kryo.Kryo;
import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
import org.slf4j.Logger;
@@ -306,6 +306,10 @@
for (FlowPath flowPath : flowPaths) {
boolean isInstalled = true;
+
+ if (flowPath.flowEntries().isEmpty()) {
+ continue;
+ }
//
// Check whether all Flow Entries have been installed
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index 0e4e3da..0d8cb38 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -41,7 +41,7 @@
import com.thinkaurelius.titan.core.TitanException;
-import com.esotericsoftware.kryo2.Kryo;
+import com.esotericsoftware.kryo.Kryo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -404,6 +404,11 @@
if (srcDpid.value() != sw.getId())
return;
deleteFlow(flowPath.flowId());
+
+ // Send flow deleted notification to the Forwarding module
+ // TODO This is a quick fix for flow-removed notifications. We
+ // should think more about the design of these notifications.
+ notificationFlowPathRemoved(flowPath);
}
/**
@@ -473,6 +478,20 @@
}
/**
+ * Generate a notification that a FlowPath has been removed from the
+ * network. This means we've received an expiry message for the flow
+ * from the switch, and send flowmods to remove any remaining parts of
+ * the path.
+ *
+ * @param flowPath FlowPath object that was removed from the network.
+ */
+ void notificationFlowPathRemoved(FlowPath flowPath) {
+ if (forwardingService != null) {
+ forwardingService.flowRemoved(flowPath);
+ }
+ }
+
+ /**
* Push modified Flow-related state as appropriate.
*
* @param modifiedFlowPaths the collection of modified Flow Paths.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
index e94d948..4915cc7 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
@@ -44,7 +44,7 @@
IOFSwitchListener {
// flag to enable FlowSynchronizer
private static final boolean enableFlowSync = true;
- protected static Logger log = LoggerFactory.getLogger(FlowProgrammer.class);
+ protected static final Logger log = LoggerFactory.getLogger(FlowProgrammer.class);
protected volatile IFloodlightProviderService floodlightProvider;
protected volatile IControllerRegistryService registryService;
protected volatile IRestApiService restApi;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
index f13d780..a718728 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
@@ -51,7 +51,8 @@
public FlowSynchronizer() {
dbHandler = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
- switchThreads = new HashMap<IOFSwitch, FutureTask<SyncResult>>(); }
+ switchThreads = new HashMap<IOFSwitch, FutureTask<SyncResult>>();
+ }
@Override
public Future<SyncResult> synchronize(IOFSwitch sw) {
@@ -102,6 +103,10 @@
Set<FlowEntryWrapper> graphEntries = getFlowEntriesFromGraph();
long step1 = System.nanoTime();
Set<FlowEntryWrapper> switchEntries = getFlowEntriesFromSwitch();
+ if (switchEntries == null) {
+ log.debug("getFlowEntriesFromSwitch() failed");
+ return null;
+ }
long step2 = System.nanoTime();
SyncResult result = compare(graphEntries, switchEntries);
long step3 = System.nanoTime();
@@ -216,12 +221,15 @@
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
+ return null;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
+ return null;
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
+ return null;
}
Set<FlowEntryWrapper> results = new HashSet<FlowEntryWrapper>();
@@ -338,7 +346,7 @@
*/
@Override
public boolean equals(Object obj){
- if(obj.getClass() == this.getClass()) {
+ if(obj != null && obj.getClass() == this.getClass()) {
FlowEntryWrapper entry = (FlowEntryWrapper) obj;
// TODO: we need to actually compare the match + actions
return this.flowEntryId.equals(entry.flowEntryId);
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
index 65bc40b..882d5fa 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -1,6 +1,5 @@
package net.onrc.onos.ofcontroller.forwarding;
-import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -16,7 +15,6 @@
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.datagrid.IDatagridService;
import net.onrc.onos.ofcontroller.core.IDeviceStorage;
@@ -27,11 +25,13 @@
import net.onrc.onos.ofcontroller.devicemanager.IOnosDeviceService;
import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
+import net.onrc.onos.ofcontroller.proxyarp.BroadcastPacketOutNotification;
+import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
import net.onrc.onos.ofcontroller.topology.TopologyManager;
import net.onrc.onos.ofcontroller.util.CallerId;
import net.onrc.onos.ofcontroller.util.DataPath;
import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
import net.onrc.onos.ofcontroller.util.FlowId;
import net.onrc.onos.ofcontroller.util.FlowPath;
@@ -53,7 +53,6 @@
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
-import com.google.common.net.InetAddresses;
public class Forwarding implements IOFMessageListener, IFloodlightModule,
IForwardingService {
@@ -61,8 +60,8 @@
private final int IDLE_TIMEOUT = 5; // seconds
private final int HARD_TIMEOUT = 0; // seconds
-
- private final int PATH_PUSHED_TIMEOUT = 3000; // milliseconds
+
+ private final CallerId callerId = new CallerId("Forwarding");
private IFloodlightProviderService floodlightProvider;
private IFlowService flowService;
@@ -72,7 +71,6 @@
private IDeviceStorage deviceStorage;
private TopologyManager topologyService;
- //private Map<Path, Long> pendingFlows;
// TODO it seems there is a Guava collection that will time out entries.
// We should see if this will work here.
private Map<Path, PushedFlow> pendingFlows;
@@ -92,31 +90,18 @@
private class PushedFlow {
public final long flowId;
- private final long pushedTime;
- public short firstHopOutPort = OFPort.OFPP_NONE.getValue();
+ public boolean installed = false;
public PushedFlow(long flowId) {
this.flowId = flowId;
- pushedTime = System.currentTimeMillis();
- }
-
- public boolean isExpired() {
- return (System.currentTimeMillis() - pushedTime) > PATH_PUSHED_TIMEOUT;
}
}
private final class Path {
- public final SwitchPort srcPort;
- public final SwitchPort dstPort;
public final MACAddress srcMac;
public final MACAddress dstMac;
- public Path(SwitchPort src, SwitchPort dst,
- MACAddress srcMac, MACAddress dstMac) {
- srcPort = new SwitchPort(new Dpid(src.dpid().value()),
- new Port(src.port().value()));
- dstPort = new SwitchPort(new Dpid(dst.dpid().value()),
- new Port(dst.port().value()));
+ public Path(MACAddress srcMac, MACAddress dstMac) {
this.srcMac = srcMac;
this.dstMac = dstMac;
}
@@ -128,17 +113,13 @@
}
Path otherPath = (Path) other;
- return srcPort.equals(otherPath.srcPort) &&
- dstPort.equals(otherPath.dstPort) &&
- srcMac.equals(otherPath.srcMac) &&
+ return srcMac.equals(otherPath.srcMac) &&
dstMac.equals(otherPath.dstMac);
}
@Override
public int hashCode() {
int hash = 17;
- hash = 31 * hash + srcPort.hashCode();
- hash = 31 * hash + dstPort.hashCode();
hash = 31 * hash + srcMac.hashCode();
hash = 31 * hash + dstMac.hashCode();
return hash;
@@ -146,8 +127,7 @@
@Override
public String toString() {
- return "(" + srcMac + " at " + srcPort + ") => ("
- + dstPort + " at " + dstMac + ")";
+ return "(" + srcMac + ") => (" + dstMac + ")";
}
}
@@ -175,6 +155,9 @@
dependencies.add(IFlowService.class);
dependencies.add(IFlowPusherService.class);
dependencies.add(IOnosDeviceService.class);
+ // We don't use the IProxyArpService directly, but reactive forwarding
+ // requires it to be loaded and answering ARP requests
+ dependencies.add(IProxyArpService.class);
return dependencies;
}
@@ -187,12 +170,8 @@
datagrid = context.getServiceImpl(IDatagridService.class);
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-
- //pendingFlows = new ConcurrentHashMap<Path, Long>();
+
pendingFlows = new HashMap<Path, PushedFlow>();
- //waitingPackets = Multimaps.synchronizedSetMultimap(
- //HashMultimap.<Long, PacketToPush>create());
- //waitingPackets = HashMultimap.create();
waitingPackets = LinkedListMultimap.create();
deviceStorage = new DeviceStorageImpl();
@@ -242,7 +221,6 @@
if (eth.isBroadcast() || eth.isMulticast()) {
handleBroadcast(sw, pi, eth);
- //return Command.CONTINUE;
}
else {
// Unicast
@@ -256,24 +234,9 @@
if (log.isTraceEnabled()) {
log.trace("Sending broadcast packet to other ONOS instances");
}
-
- IPv4 ipv4Packet = (IPv4) eth.getPayload();
-
- // TODO We'll put the destination address here, because the current
- // architecture needs an address. Addresses are only used for replies
- // however, which don't apply to non-ARP packets. The ArpMessage class
- // has become a bit too overloaded and should be refactored to
- // handle all use cases nicely.
- InetAddress targetAddress =
- InetAddresses.fromInteger(ipv4Packet.getDestinationAddress());
-
- // Piggy-back on the ARP mechanism to broadcast this packet out the
- // edge. Luckily the ARP module doesn't check that the packet is
- // actually ARP before broadcasting, so we can trick it into sending
- // our non-ARP packets.
- // TODO This should be refactored later to account for the new use case.
- datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(),
- -1L, (short)-1, sw.getId(), pi.getInPort()));
+
+ datagrid.sendPacketOutNotification(new BroadcastPacketOutNotification(
+ eth.serialize(), sw.getId(), pi.getInPort()));
}
private void handlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
@@ -303,7 +266,6 @@
long destinationDpid = HexString.toLong(switchObject.getDPID());
// TODO SwitchPort, Dpid and Port should probably be immutable
- // (also, are Dpid and Port are even necessary?)
SwitchPort srcSwitchPort = new SwitchPort(
new Dpid(sw.getId()), new Port(pi.getInPort()));
SwitchPort dstSwitchPort = new SwitchPort(
@@ -312,26 +274,50 @@
MACAddress srcMacAddress = MACAddress.valueOf(eth.getSourceMACAddress());
MACAddress dstMacAddress = MACAddress.valueOf(eth.getDestinationMACAddress());
-
FlowPath flowPath, reverseFlowPath;
- Path pathspec = new Path(srcSwitchPort, dstSwitchPort,
- srcMacAddress, dstMacAddress);
+ Path pathspec = new Path(srcMacAddress, dstMacAddress);
// TODO check concurrency
synchronized (lock) {
PushedFlow existingFlow = pendingFlows.get(pathspec);
- //Long existingFlowId = pendingFlows.get(pathspec);
-
- if (existingFlow != null && !existingFlow.isExpired()) {
+
+ if (existingFlow != null) {
+ // We've already installed a flow for this pair of MAC addresses
log.debug("Found existing flow {}",
HexString.toHexString(existingFlow.flowId));
OFPacketOut po = constructPacketOut(pi, sw);
- if (existingFlow.firstHopOutPort != OFPort.OFPP_NONE.getValue()) {
+ // Find the correct port here. We just assume the PI is from
+ // the first hop switch, but this is definitely not always
+ // the case. We'll have to retrieve the flow from HZ every time
+ // because it could change (be rerouted) sometimes.
+ if (existingFlow.installed) {
// Flow has been sent to the switches so it is safe to
// send a packet out now
- sendPacketOut(sw, po, existingFlow.firstHopOutPort);
+ FlowPath flow = datagrid.getFlow(new FlowId(existingFlow.flowId));
+ FlowEntry flowEntryForThisSwitch = null;
+
+ if (flow != null) {
+ for (FlowEntry flowEntry : flow.flowEntries()) {
+ if (flowEntry.dpid().equals(new Dpid(sw.getId()))) {
+ flowEntryForThisSwitch = flowEntry;
+ break;
+ }
+ }
+ }
+
+ if (flowEntryForThisSwitch == null) {
+ // If we don't find a flow entry for that switch, then we're
+ // in the middle of a rerouting (or something's gone wrong).
+ // This packet will be dropped as a victim of the rerouting.
+ log.debug("Dropping packet on flow {} between {}-{}, flow path {}",
+ new Object[] {new FlowId(existingFlow.flowId),
+ srcMacAddress, dstMacAddress, flow});
+ }
+ else {
+ sendPacketOut(sw, po, flowEntryForThisSwitch.outPort().value());
+ }
}
else {
// Flow has not yet been sent to switches so save the
@@ -341,21 +327,16 @@
}
return;
}
-
- //log.debug("Couldn't match {} in {}", pathspec, pendingFlows);
-
+
log.debug("Adding new flow between {} at {} and {} at {}",
new Object[]{srcMacAddress, srcSwitchPort, dstMacAddress, dstSwitchPort});
-
- CallerId callerId = new CallerId("Forwarding");
-
DataPath datapath = new DataPath();
datapath.setSrcPort(srcSwitchPort);
datapath.setDstPort(dstSwitchPort);
flowPath = new FlowPath();
- flowPath.setInstallerId(callerId);
+ flowPath.setInstallerId(new CallerId(callerId));
flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
@@ -375,7 +356,7 @@
// TODO implement copy constructor for FlowPath
reverseFlowPath = new FlowPath();
- reverseFlowPath.setInstallerId(callerId);
+ reverseFlowPath.setInstallerId(new CallerId(callerId));
reverseFlowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
reverseFlowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
reverseFlowPath.setIdleTimeout(IDLE_TIMEOUT);
@@ -387,9 +368,7 @@
reverseFlowPath.flowEntryMatch().enableEthernetFrameType(Ethernet.TYPE_IPv4);
reverseFlowPath.setDataPath(reverseDataPath);
reverseFlowPath.dataPath().srcPort().dpid().toString();
-
- // TODO what happens if no path exists? cleanup
-
+
FlowId flowId = new FlowId(flowService.getNextFlowEntryId());
FlowId reverseFlowId = new FlowId(flowService.getNextFlowEntryId());
@@ -397,50 +376,23 @@
reverseFlowPath.setFlowId(reverseFlowId);
OFPacketOut po = constructPacketOut(pi, sw);
- Path reversePathSpec = new Path(dstSwitchPort, srcSwitchPort,
- dstMacAddress, srcMacAddress);
+ Path reversePathSpec = new Path(dstMacAddress, srcMacAddress);
// Add to waiting lists
- //pendingFlows.put(pathspec, flowId.value());
- //pendingFlows.put(reversePathSpec, reverseFlowId.value());
pendingFlows.put(pathspec, new PushedFlow(flowId.value()));
pendingFlows.put(reversePathSpec, new PushedFlow(reverseFlowId.value()));
waitingPackets.put(flowId.value(), new PacketToPush(po, sw.getId()));
}
+ log.debug("Adding reverse {} to {} flowid {}", new Object[] {
+ dstMacAddress, srcMacAddress, reverseFlowPath.flowId()});
flowService.addFlow(reverseFlowPath);
+ log.debug("Adding forward {} to {} flowid {}", new Object[] {
+ srcMacAddress, dstMacAddress, flowPath.flowId()});
flowService.addFlow(flowPath);
}
-
- /*
- private boolean flowExists(SwitchPort srcPort, MACAddress srcMac,
- SwitchPort dstPort, MACAddress dstMac) {
- for (FlowPath flow : datagridService.getAllFlows()) {
- FlowEntryMatch match = flow.flowEntryMatch();
- // TODO implement FlowEntryMatch.equals();
- // This is painful to do properly without support in the FlowEntryMatch
- boolean same = true;
- if (!match.srcMac().equals(srcMac) ||
- !match.dstMac().equals(dstMac)) {
- same = false;
- }
- if (!flow.dataPath().srcPort().equals(srcPort) ||
- !flow.dataPath().dstPort().equals(dstPort)) {
- same = false;
- }
-
- if (same) {
- log.debug("found flow entry that's the same {}-{}:::{}-{}",
- new Object[] {srcPort, srcMac, dstPort, dstMac});
- return true;
- }
- }
-
- return false;
- }
- */
private OFPacketOut constructPacketOut(OFPacketIn pi, IOFSwitch sw) {
OFPacketOut po = new OFPacketOut();
@@ -467,10 +419,45 @@
flowInstalled(flowPath);
}
}
+
+ @Override
+ public void flowRemoved(FlowPath removedFlowPath) {
+ if (!removedFlowPath.installerId().equals(callerId)) {
+ // Not our flow path, ignore
+ return;
+ }
+
+ MACAddress srcMacAddress = removedFlowPath.flowEntryMatch().srcMac();
+ MACAddress dstMacAddress = removedFlowPath.flowEntryMatch().dstMac();
+
+ Path removedPath = new Path(srcMacAddress, dstMacAddress);
+
+ synchronized (lock) {
+ pendingFlows.remove(removedPath);
+
+ // There *shouldn't* be any packets queued if the flow has
+ // just been removed.
+ List<PacketToPush> packets =
+ waitingPackets.removeAll(removedFlowPath.flowId().value());
+ if (!packets.isEmpty()) {
+ log.warn("Removed flow {} has packets queued",
+ removedFlowPath.flowId());
+ }
+ }
+ }
private void flowInstalled(FlowPath installedFlowPath) {
long flowId = installedFlowPath.flowId().value();
+ if (!installedFlowPath.installerId().equals(callerId)) {
+ // Not our flow path, ignore
+ return;
+ }
+
+ // TODO waiting packets should time out. We could request a path that
+ // can't be installed right now because of a network partition. The path
+ // may eventually be installed, but we may have received thousands of
+ // packets in the meantime and probably don't want to send very old packets.
short outPort =
installedFlowPath.flowEntries().get(0).outPort().value();
@@ -479,19 +466,17 @@
Collection<PacketToPush> packets;
synchronized (lock) {
- log.debug("Flow {} has been installed, sending queued packets",
- installedFlowPath.flowId());
-
packets = waitingPackets.removeAll(flowId);
+ log.debug("Flow {} has been installed, sending {} queued packets",
+ installedFlowPath.flowId(), packets.size());
+
// remove pending flows entry
- Path installedPath = new Path(installedFlowPath.dataPath().srcPort(),
- installedFlowPath.dataPath().dstPort(),
- srcMacAddress, dstMacAddress);
- //pendingFlows.remove(pathToRemove);
+ Path installedPath = new Path(srcMacAddress, dstMacAddress);
PushedFlow existingFlow = pendingFlows.get(installedPath);
- if (existingFlow != null)
- existingFlow.firstHopOutPort = outPort;
+ if (existingFlow != null) {
+ existingFlow.installed = true;
+ }
}
for (PacketToPush packet : packets) {
@@ -509,4 +494,5 @@
flowPusher.add(sw, po);
}
+
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
index e5bd714..0e0d1da 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
@@ -22,4 +22,12 @@
* been installed in the network.
*/
public void flowsInstalled(Collection<FlowPath> installedFlowPaths);
+
+ /**
+ * Notify the Forwarding module that a flow has expired and been
+ * removed from the network.
+ *
+ * @param removedFlowPath The FlowPath that was removed
+ */
+ public void flowRemoved(FlowPath removedFlowPath);
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
deleted file mode 100644
index 44b9ea0..0000000
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package net.onrc.onos.ofcontroller.proxyarp;
-
-import java.io.Serializable;
-import java.net.InetAddress;
-import net.floodlightcontroller.util.MACAddress;
-
-// TODO This is getting very messy!!! Needs refactoring
-public class ArpMessage implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- private final Type type;
- private final InetAddress forAddress;
- private final byte[] packetData;
-
- // ARP reply message needs MAC info
- private final MACAddress mac;
- // Only send the ARP request message to the device attachment needs the
- // attachment switch and port.
- private final long outSwitch;
- private final short outPort;
-
- private final long inSwitch;
- private final short inPort;
-
- public enum Type {
- REQUEST,
- REPLY
- }
-
- private ArpMessage(Type type, InetAddress address, byte[] eth,
- long outSwitch, short outPort, long inSwitch, short inPort) {
- this.type = type;
- this.forAddress = address;
- this.packetData = eth;
- this.mac = null;
- this.outSwitch = -1;
- this.outPort = -1;
- this.inSwitch = inSwitch;
- this.inPort = inPort;
- }
-
- private ArpMessage(Type type, InetAddress address) {
- this.type = type;
- this.forAddress = address;
- this.packetData = null;
- this.mac = null;
- this.outSwitch = -1;
- this.outPort = -1;
-
- this.inSwitch = -1;
- this.inPort = -1;
- }
- // the ARP reply message with MAC
- private ArpMessage(Type type, InetAddress address, MACAddress mac) {
- this.type = type;
- this.forAddress = address;
- this.packetData = null;
- this.mac = mac;
- this.outSwitch = -1;
- this.outPort = -1;
-
- this.inSwitch = -1;
- this.inPort = -1;
- }
-
- // construct ARP request message with attachment switch and port
- private ArpMessage(Type type, InetAddress address, byte[] arpRequest,
- long outSwitch, short outPort) {
- this.type = type;
- this.forAddress = address;
- this.packetData = arpRequest;
- this.mac = null;
- this.outSwitch = outSwitch;
- this.outPort = outPort;
-
- this.inSwitch = -1;
- this.inPort = -1;
- }
-
- // TODO Awful quick fix - caller has to supply dummy outSwitch and outPort
- public static ArpMessage newRequest(InetAddress forAddress, byte[] arpRequest,
- long outSwitch, short outPort, long inSwitch, short inPort) {
- return new ArpMessage(Type.REQUEST, forAddress, arpRequest,
- outSwitch, outPort, inSwitch, inPort);
- }
-
- public static ArpMessage newReply(InetAddress forAddress) {
- return new ArpMessage(Type.REPLY, forAddress);
- }
-
- //ARP reply message with MAC
- public static ArpMessage newReply(InetAddress forAddress, MACAddress mac) {
- return new ArpMessage(Type.REPLY, forAddress, mac);
- }
-
- //ARP request message with attachment switch and port
- public static ArpMessage newRequest(InetAddress forAddress,
- byte[] arpRequest, long outSwitch, short outPort ) {
- return new ArpMessage(Type.REQUEST, forAddress, arpRequest, outSwitch,
- outPort);
- }
-
- public Type getType() {
- return type;
- }
-
- public InetAddress getAddress() {
- return forAddress;
- }
-
- public byte[] getPacket() {
- return packetData;
- }
-
- public MACAddress getMAC() {
- return mac;
- }
-
- public long getOutSwitch() {
- return outSwitch;
- }
-
- public short getOutPort() {
- return outPort;
- }
-
- public long getInSwitch() {
- return inSwitch;
- }
-
- public short getInPort() {
- return inPort;
- }
-}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java
new file mode 100644
index 0000000..a8afc55
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java
@@ -0,0 +1,28 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+import net.floodlightcontroller.util.MACAddress;
+
+public class ArpReplyNotification implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private InetAddress targetAddress;
+ private MACAddress targetMacAddress;
+
+ public ArpReplyNotification(InetAddress targetAddress, MACAddress targetMacAddress) {
+ this.targetAddress = targetAddress;
+ this.targetMacAddress = targetMacAddress;
+ }
+
+ public InetAddress getTargetAddress() {
+ return targetAddress;
+ }
+
+ public MACAddress getTargetMacAddress() {
+ return targetMacAddress;
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
new file mode 100644
index 0000000..73d2163
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
@@ -0,0 +1,34 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+/**
+ * Notification to all ONOS instances to broadcast this packet out the edge of
+ * the network. The edge is defined as any port that doesn't have a link to
+ * another switch. The one exception is the port that the packet was received
+ * on.
+ *
+ */
+public class BroadcastPacketOutNotification extends
+ PacketOutNotification {
+
+ private static final long serialVersionUID = 1L;
+
+ private final long inSwitch;
+ private final short inPort;
+
+ public BroadcastPacketOutNotification(byte[] packet, long inSwitch,
+ short inPort) {
+ super(packet);
+
+ this.inSwitch = inSwitch;
+ this.inPort = inPort;
+ }
+
+ public long getInSwitch() {
+ return inSwitch;
+ }
+
+ public short getInPort() {
+ return inPort;
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java
deleted file mode 100644
index 4ec32ec..0000000
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package net.onrc.onos.ofcontroller.proxyarp;
-
-public interface IArpEventHandler {
-
- /**
- * Notify the ARP event handler that an ARP request has been received.
- * @param id The string ID of the ARP request
- * @param arpRequest The ARP request packet
- */
- public void arpRequestNotification(ArpMessage arpMessage);
-}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java
new file mode 100644
index 0000000..75f1d5d
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java
@@ -0,0 +1,5 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+public interface IArpReplyEventHandler {
+ public void arpReplyEvent(ArpReplyNotification arpReply);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java
new file mode 100644
index 0000000..86b3728
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java
@@ -0,0 +1,18 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+/**
+ * Classes may implement this interface if they wish to subscribe to
+ * packet out notifications from the datagrid service. Packet out notifications
+ * are used to direct other ONOS instances to send packets out particular
+ * ports under their control.
+ *
+ */
+public interface IPacketOutEventHandler {
+
+ /**
+ * Notify the packet out event handler that an packet out notification has
+ * been received.
+ * @param packetOutNotification An object describing the notification
+ */
+ public void packetOutNotification(PacketOutNotification packetOutNotification);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java
new file mode 100644
index 0000000..3d37d25
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java
@@ -0,0 +1,21 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+import java.io.Serializable;
+
+/**
+ * A PacketOutNotification contains data sent between ONOS instances that
+ * directs other instances to send a packet out a set of ports.
+ * This is an abstract base class that will be subclassed by specific
+ * types of notifications.
+ *
+ */
+public abstract class PacketOutNotification implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ protected final byte[] packet;
+
+ public PacketOutNotification(byte[] packet) {
+ this.packet = packet;
+ }
+}
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 2b4b0b1..f5fee45 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -37,6 +37,7 @@
import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
import net.onrc.onos.ofcontroller.core.internal.TopoSwitchServiceImpl;
+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;
@@ -58,7 +59,8 @@
import com.google.common.net.InetAddresses;
public class ProxyArpManager implements IProxyArpService, IOFMessageListener,
- IArpEventHandler, IFloodlightModule {
+ IPacketOutEventHandler, IArpReplyEventHandler,
+ IFloodlightModule {
private final static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
private final long ARP_TIMER_PERIOD = 100; //ms
@@ -70,6 +72,7 @@
private IDatagridService datagrid;
private IConfigInfoService configService;
private IRestApiService restApi;
+ private IFlowPusherService flowPusher;
private IDeviceStorage deviceStorage;
private volatile ITopoSwitchService topoSwitchService;
@@ -153,6 +156,7 @@
dependencies.add(IRestApiService.class);
dependencies.add(IDatagridService.class);
dependencies.add(IConfigInfoService.class);
+ dependencies.add(IFlowPusherService.class);
return dependencies;
}
@@ -164,6 +168,7 @@
this.datagrid = context.getServiceImpl(IDatagridService.class);
this.configService = context.getServiceImpl(IConfigInfoService.class);
this.restApi = context.getServiceImpl(IRestApiService.class);
+ this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
//arpCache = new ArpCache();
@@ -181,7 +186,8 @@
restApi.addRestletRoutable(new ArpWebRoutable());
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- datagrid.registerArpEventHandler(this);
+ datagrid.registerPacketOutEventHandler(this);
+ datagrid.registerArpReplyEventHandler(this);
deviceStorage = new DeviceStorageImpl();
deviceStorage.init("","");
@@ -290,8 +296,10 @@
handleArpRequest(sw, pi, arp, eth);
}
else if (arp.getOpCode() == ARP.OP_REPLY) {
- handleArpReply(sw, pi, arp);
- sendToOtherNodesReply(eth, pi);
+ // For replies we simply send a notification via Hazelcast
+ sendArpReplyNotification(eth, pi);
+
+ //handleArpReply(sw, pi, arp);
}
// Stop ARP packets here
@@ -345,7 +353,9 @@
}
// We don't know the device so broadcast the request out
- sendToOtherNodes(eth, sw.getId(), pi);
+ datagrid.sendPacketOutNotification(
+ new BroadcastPacketOutNotification(eth.serialize(),
+ sw.getId(), pi.getInPort()));
}
else {
// Even if the device exists in our database, we do not reply to
@@ -362,7 +372,6 @@
// sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
- log.trace("Checking the device info from DB is still valid or not");
Iterable<IPortObject> outPorts = targetDevice.getAttachedPorts();
if (!outPorts.iterator().hasNext()){
@@ -371,19 +380,26 @@
" - broadcasting", macAddress);
}
- sendToOtherNodes(eth, sw.getId(), pi);
+ datagrid.sendPacketOutNotification(
+ new BroadcastPacketOutNotification(eth.serialize(),
+ sw.getId(), pi.getInPort()));
}
else {
for (IPortObject portObject : outPorts) {
- long outSwitch = 0;
- short outPort = 0;
+ //long outSwitch = 0;
+ //short outPort = 0;
+ /*
if (!portObject.getLinkedPorts().iterator().hasNext()) {
outPort = portObject.getNumber();
+ }*/
+ if (portObject.getLinkedPorts().iterator().hasNext()) {
+ continue;
}
+ short outPort = portObject.getNumber();
ISwitchObject outSwitchObject = portObject.getSwitch();
- outSwitch = HexString.toLong(outSwitchObject.getDPID());
+ long outSwitch = HexString.toLong(outSwitchObject.getDPID());
if (log.isTraceEnabled()) {
log.trace("Probing device {} on port {}/{}",
@@ -391,7 +407,9 @@
HexString.toHexString(outSwitch), outPort});
}
- sendToOtherNodes(eth, pi, outSwitch, outPort);
+ datagrid.sendPacketOutNotification(
+ new SinglePacketOutNotification(eth.serialize(),
+ outSwitch, outPort));
}
}
}
@@ -517,50 +535,7 @@
}
}
- private void sendToOtherNodes(Ethernet eth, long inSwitchId, OFPacketIn pi) {
- ARP arp = (ARP) eth.getPayload();
-
- if (log.isTraceEnabled()) {
- log.trace("Sending ARP request for {} to other ONOS instances",
- inetAddressToString(arp.getTargetProtocolAddress()));
- }
-
- InetAddress targetAddress;
- try {
- targetAddress = InetAddress.getByAddress(arp.getTargetProtocolAddress());
- } catch (UnknownHostException e) {
- log.error("Unknown host", e);
- return;
- }
-
- datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(),
- -1L, (short)-1, inSwitchId, pi.getInPort()));
- }
-
- //hazelcast to other ONOS instances to send the ARP packet out on outPort of outSwitch
- private void sendToOtherNodes(Ethernet eth, OFPacketIn pi, long outSwitch, short outPort) {
- ARP arp = (ARP) eth.getPayload();
-
- if (log.isTraceEnabled()) {
- log.trace("Sending ARP request for {} to other ONOS instances with outSwitch {} ",
- inetAddressToString(arp.getTargetProtocolAddress()), String.valueOf(outSwitch));
- }
-
- InetAddress targetAddress;
- try {
- targetAddress = InetAddress.getByAddress(arp.getTargetProtocolAddress());
- } catch (UnknownHostException e) {
- log.error("Unknown host", e);
- return;
- }
-
- datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(), outSwitch, outPort));
- //datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize()));
-
-
- }
-
- private void sendToOtherNodesReply(Ethernet eth, OFPacketIn pi) {
+ private void sendArpReplyNotification(Ethernet eth, OFPacketIn pi) {
ARP arp = (ARP) eth.getPayload();
if (log.isTraceEnabled()) {
@@ -577,12 +552,14 @@
log.error("Unknown host", e);
return;
}
-
- datagrid.sendArpRequest(ArpMessage.newReply(targetAddress, mac));
- //datagrid.sendArpReply(ArpMessage.newRequest(targetAddress, eth.serialize()));
-
+
+ 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();
@@ -673,12 +650,7 @@
po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength
+ arpRequest.length);
- try {
- sw.write(po, null);
- sw.flush();
- } catch (IOException e) {
- log.error("Failure writing packet out to switch", e);
- }
+ flowPusher.add(sw, po);
}
if (log.isTraceEnabled()) {
@@ -712,12 +684,7 @@
return;
}
- try {
- sw.write(po, null);
- sw.flush();
- } catch (IOException e) {
- log.error("Failure writing packet out to switch", e);
- }
+ flowPusher.add(sw, po);
}
private void sendArpReply(ARP arpRequest, long dpid, short port, MACAddress targetMac) {
@@ -740,7 +707,6 @@
.setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
-
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
.setSourceMACAddress(targetMac.toBytes())
@@ -775,12 +741,7 @@
return;
}
- try {
- sw.write(msgList, null);
- sw.flush();
- } catch (IOException e) {
- log.error("Failure writing packet out to switch", e);
- }
+ flowPusher.add(sw, po);
}
private String inetAddressToString(byte[] bytes) {
@@ -820,9 +781,6 @@
}
/*
- * IArpEventHandler methods
- */
-
@Override
public void arpRequestNotification(ArpMessage arpMessage) {
log.debug("Received ARP notification from other instances");
@@ -844,6 +802,7 @@
break;
}
}
+ */
private void sendArpReplyToWaitingRequesters(InetAddress address, MACAddress mac) {
log.debug("Sending ARP reply for {} to requesters",
@@ -876,4 +835,33 @@
request.dispatchReply(address, mac);
}
}
+
+ @Override
+ public void arpReplyEvent(ArpReplyNotification arpReply) {
+ log.debug("Received ARP reply notification for {}",
+ arpReply.getTargetAddress());
+ sendArpReplyToWaitingRequesters(arpReply.getTargetAddress(),
+ arpReply.getTargetMacAddress());
+ }
+
+ @Override
+ public void packetOutNotification(
+ PacketOutNotification packetOutNotification) {
+
+ if (packetOutNotification instanceof SinglePacketOutNotification) {
+ SinglePacketOutNotification notification =
+ (SinglePacketOutNotification) packetOutNotification;
+ sendArpRequestOutPort(notification.packet, notification.getOutSwitch(),
+ notification.getOutPort());
+ }
+ else if (packetOutNotification instanceof BroadcastPacketOutNotification) {
+ BroadcastPacketOutNotification notification =
+ (BroadcastPacketOutNotification) packetOutNotification;
+ broadcastArpRequestOutMyEdge(notification.packet,
+ notification.getInSwitch(), notification.getInPort());
+ }
+ else {
+ log.warn("Unknown packet out notification received");
+ }
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
new file mode 100644
index 0000000..1919d87
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
@@ -0,0 +1,30 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+/**
+ * Notification to another ONOS instance to send a packet out a single port.
+ *
+ */
+public class SinglePacketOutNotification extends PacketOutNotification {
+
+ private static final long serialVersionUID = 1L;
+
+ private final long outSwitch;
+ private final short outPort;
+
+ public SinglePacketOutNotification(byte[] packet, long outSwitch,
+ short outPort) {
+ super(packet);
+
+ this.outSwitch = outSwitch;
+ this.outPort = outPort;
+ }
+
+ public long getOutSwitch() {
+ return outSwitch;
+ }
+
+ public short getOutPort() {
+ return outPort;
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
index a80f961..f326f4c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -74,7 +74,7 @@
/**
* Init the module.
- * @param
+ *
* @param config the database configuration file to use for
* the initialization.
*/
@@ -219,7 +219,7 @@
*/
@Override
public void dropTopology(Topology topology) {
- topology = null;
+ // nothing to do
}
/**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java b/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
index 0607533..a0217d4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
@@ -12,6 +12,15 @@
* Default constructor.
*/
public CallerId() {}
+
+ /**
+ * Copy constructor
+ * @param otherCallerId
+ */
+ public CallerId(CallerId otherCallerId) {
+ // Note: make a full copy if we change value to a mutable type
+ value = otherCallerId.value;
+ }
/**
* Constructor from a string value.
@@ -49,4 +58,20 @@
public String toString() {
return value;
}
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof CallerId)) {
+ return false;
+ }
+
+ CallerId otherCallerId = (CallerId) other;
+
+ return value.equals(otherCallerId.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java b/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
index bd91daa..81223d2 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
@@ -13,7 +13,7 @@
@JsonDeserialize(using=DpidDeserializer.class)
@JsonSerialize(using=DpidSerializer.class)
public class Dpid {
- static public long UNKNOWN = 0;
+ static public final long UNKNOWN = 0;
private long value;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
index 1355fe0..5998dcd 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
@@ -4,7 +4,6 @@
import java.util.TreeMap;
import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
import net.onrc.onos.ofcontroller.topology.TopologyElement;
import net.onrc.onos.ofcontroller.util.CallerId;
import net.onrc.onos.ofcontroller.util.DataPath;
@@ -31,7 +30,7 @@
import net.onrc.onos.ofcontroller.util.Switch;
import net.onrc.onos.ofcontroller.util.SwitchPort;
-import com.esotericsoftware.kryo2.Kryo;
+import com.esotericsoftware.kryo.Kryo;
/**
* Class factory for allocating Kryo instances for
@@ -152,9 +151,6 @@
kryo.register(TopologyElement.class);
kryo.register(TopologyElement.Type.class);
kryo.register(TreeMap.class);
-
- //ARP message
- kryo.register(ArpMessage.class);
return kryo;
}