merge from upstream/master
diff --git a/conf/cassandra.titan b/conf/cassandra.titan
index c36ecc0..9a9b00f 100644
--- a/conf/cassandra.titan
+++ b/conf/cassandra.titan
@@ -2,6 +2,6 @@
storage.hostname=localhost
storage.keyspace=onos
storage.connection-pool-size=4096
-storage.replication-factor=3
+storage.replication-factor=1
storage.write-consistency-level=ALL
storage.read-consistency-level=ONE
diff --git a/conf/hazelcast.titan b/conf/hazelcast.titan
new file mode 100644
index 0000000..d4719fa
--- /dev/null
+++ b/conf/hazelcast.titan
@@ -0,0 +1,2 @@
+storage.backend=hazelcastcache
+storage.directory=/tmp/cache
diff --git a/conf/hazelcast.xml b/conf/hazelcast.xml
index 11bef59..84c7354 100644
--- a/conf/hazelcast.xml
+++ b/conf/hazelcast.xml
@@ -101,5 +101,6 @@
<properties>
<property name="hazelcast.logging.type">slf4j</property>
+ <property name="hazelcast.version.check.enabled">false</property>
</properties>
</hazelcast>
diff --git a/conf/onos-embedded.properties b/conf/onos-embedded.properties
index e280e41..8ec84f4 100644
--- a/conf/onos-embedded.properties
+++ b/conf/onos-embedded.properties
@@ -3,9 +3,7 @@
net.floodlightcontroller.threadpool.ThreadPool,\
net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
-net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
net.floodlightcontroller.counter.CounterStore,\
-net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.ui.web.StaticWebRoutable,\
net.onrc.onos.datagrid.HazelcastDatagrid,\
net.onrc.onos.ofcontroller.flowmanager.FlowManager,\
diff --git a/conf/onos.properties b/conf/onos.properties
index f7bffb2..174df20 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -3,9 +3,7 @@
net.floodlightcontroller.threadpool.ThreadPool,\
net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
-net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
net.floodlightcontroller.counter.CounterStore,\
-net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.ui.web.StaticWebRoutable,\
net.onrc.onos.datagrid.HazelcastDatagrid,\
net.onrc.onos.ofcontroller.flowmanager.FlowManager,\
diff --git a/curator/curator-client-1.3.5-SNAPSHOT.jar b/curator/curator-client-1.3.5-SNAPSHOT.jar
new file mode 100644
index 0000000..c22d602
--- /dev/null
+++ b/curator/curator-client-1.3.5-SNAPSHOT.jar
Binary files differ
diff --git a/curator/curator-framework-1.3.5-SNAPSHOT.jar b/curator/curator-framework-1.3.5-SNAPSHOT.jar
new file mode 100644
index 0000000..1b89270
--- /dev/null
+++ b/curator/curator-framework-1.3.5-SNAPSHOT.jar
Binary files differ
diff --git a/curator/curator-recipes-1.3.5-SNAPSHOT.jar b/curator/curator-recipes-1.3.5-SNAPSHOT.jar
new file mode 100644
index 0000000..30efe51
--- /dev/null
+++ b/curator/curator-recipes-1.3.5-SNAPSHOT.jar
Binary files differ
diff --git a/curator/curator-x-discovery-1.3.5-SNAPSHOT.jar b/curator/curator-x-discovery-1.3.5-SNAPSHOT.jar
new file mode 100644
index 0000000..147417e
--- /dev/null
+++ b/curator/curator-x-discovery-1.3.5-SNAPSHOT.jar
Binary files differ
diff --git a/lib/jamm-0.2.5.jar b/lib/jamm-0.2.5.jar
index e9baf75..ef8750d 100644
--- a/lib/jamm-0.2.5.jar
+++ b/lib/jamm-0.2.5.jar
Binary files differ
diff --git a/perf-scripts/flow-sync-perf.py b/perf-scripts/flow-sync-perf.py
new file mode 100755
index 0000000..f0af050
--- /dev/null
+++ b/perf-scripts/flow-sync-perf.py
@@ -0,0 +1,210 @@
+#!/usr/bin/python
+'''
+ Script that tests Flow Synchronizer performance
+ Author: Brian O'Connor <bocon@onlab.us>
+
+ Usage:
+ 1. Ensure that ONOS is running
+ 2. sudo ./flow-sync-perf.sh <list of tests>
+ e.g. sudo ./flow-sync-perf.sh 1 10 100 1000
+ or to run the default tests:
+ sudo ./flow-sync-perf.sh
+ 3. Results are CSV files in a date stamped directory
+'''
+
+import csv
+import os
+import sys
+from time import sleep, strftime
+from subprocess import Popen, call, check_output, PIPE
+from mininet.net import Mininet
+from mininet.topo import SingleSwitchTopo
+from mininet.node import RemoteController
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+try:
+ import pexpect
+except:
+ # install pexpect if it cannot be found and re-import
+ print '* Installing Pexpect'
+ call( 'apt-get install -y python-pexpect', stdout=PIPE, shell=True )
+ import pexpect
+
+ONOS_HOME = '..'
+ONOS_LOG = '%s/onos-logs/onos.%s.log' % ( ONOS_HOME, check_output( 'hostname').strip() )
+print "ONOS Log File:", ONOS_LOG
+
+# Verify that tcpkill is installed
+if not Popen( 'which tcpkill', stdout=PIPE, shell=True).communicate():
+ print '* Installing tcpkill'
+ call( 'apt-get install -y dsniff', stdout=PIPE, shell=True )
+
+# ----------------- Tests scenarios -------------------------
+def doNothing(n):
+ print "Doing nothing with %d flows..." % n
+
+def addFakeFlows(n):
+ print "Adding %d random flows to switch..." % n
+ for i in range( 1, (n+1) ):
+ a = i / (256*256) % 256
+ b = i / 256 % 256
+ c = i % 256
+ ip = '10.%d.%d.%d' % (a,b,c)
+ call( 'ovs-ofctl add-flow s1 "ip, nw_src=%s/32, idle_timeout=0, hard_timeout=0, cookie=%d, actions=output:2"' % ( ip, i ), shell=True )
+
+def delFlowsFromSwitch(n):
+ print "Removing all %d flows from switch..." % n
+ call( 'ovs-ofctl del-flows s1', shell=True )
+
+
+# ----------------- Utility Functions -------------------------
+def wait(time, msg=None):
+ if msg:
+ print msg,
+ for i in range(time):
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ sleep(1)
+ print ". done"
+
+def startNet(net):
+ tail = pexpect.spawn( 'tail -0f %s' % ONOS_LOG )
+ sleep(1)
+ net.start()
+ print "Waiting for ONOS to detech the switch..."
+ index = tail.expect(['Sync time \(ms\)', pexpect.EOF, pexpect.TIMEOUT])
+ if index >= 1:
+ print '* ONOS not started'
+ net.stop()
+ exit(1)
+ tail.terminate()
+
+def dumpFlows():
+ return check_output( 'ovs-ofctl dump-flows s1', shell=True )
+
+def addFlowsToONOS(n):
+ print "Adding %d flows to ONOS" % n,
+ call( './generate_flows.py 1 %d > /tmp/flows.txt' % n, shell=True )
+ #call( '%s/web/add_flow.py -m onos -f /tmp/flows.txt' % ONOS_HOME, shell=True )
+ p = Popen( '%s/web/add_flow.py -m onos -f /tmp/flows.txt' % ONOS_HOME, shell=True )
+ while p.poll() is None:
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ sleep(1)
+ print ". done\nWaiting for flow entries to be added to switch",
+ while True:
+ output = check_output( 'ovs-ofctl dump-flows s1', shell=True )
+ lines = len(output.split('\n'))
+ if lines >= (n+2):
+ break
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ sleep(1)
+ print ". done\nWaiting for flow entries to be visible in network graph",
+ while True:
+ output = pexpect.spawn( '%s/web/get_flow.py all' % ONOS_HOME )
+ count = 0
+ while count < n:
+ if output.expect(['FlowEntry', pexpect.EOF], timeout=2000) == 1:
+ break
+ count += 1
+ print '. done'
+ return
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ sleep(5)
+
+def removeFlowsFromONOS(checkSwitch=True):
+ print "Removing all flows from ONOS",
+ #call( '%s/web/delete_flow.py all' % ONOS_HOME, shell=True )
+ p = Popen( '%s/web/delete_flow.py all' % ONOS_HOME, shell=True )
+ while p.poll() is None:
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ sleep(1)
+ print ". done"
+ if checkSwitch:
+ print "Waiting for flow entries to be removed from switch",
+ while True:
+ output = check_output( 'ovs-ofctl dump-flows s1', shell=True )
+ lines = len(output.split('\n'))
+ if lines == 2:
+ break
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ sleep(1)
+ print ". done"
+ print "Waiting for flow entries to be removed from network graph",
+ while True:
+ output = pexpect.spawn( '%s/web/get_flow.py all' % ONOS_HOME )
+ if output.expect(['FlowEntry', pexpect.EOF], timeout=2000) == 1:
+ break
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ sleep(5)
+ print '. done'
+
+# ----------------- Running the test and output -------------------------
+def test(i, fn):
+ # Start tailing the onos log
+ tail = pexpect.spawn( "tail -0f %s" % ONOS_LOG )
+ # disconnect the switch from the controller using tcpkill
+ tcp = Popen( 'exec tcpkill -i lo -9 port 6633 > /dev/null 2>&1', shell=True )
+ # wait until the switch has been disconnected
+ tail.expect( 'Switch removed' )
+ # call the test function
+ fn(i)
+ # dump to flows to ensure they have all made it to ovs
+ dumpFlows()
+ # end tcpkill process to reconnect the switch to the controller
+ tcp.terminate()
+ tail.expect('Sync time \(ms\):', timeout=6000)
+ tail.expect('([\d.]+,?)+\s')
+ print "* Results:", tail.match.group(0)
+ tail.terminate()
+ wait(3, "Waiting for 3 seconds between tests")
+ return tail.match.group(0).strip().split(',')
+
+def initResults(files):
+ headers = ['# of FEs', 'Flow IDs from Graph', 'FEs from Switch', 'Compare',
+ 'Read FE from graph', 'Extract FE', 'Push', 'Total' ]
+ for filename in files.values():
+ with open(filename, 'w') as csvfile:
+ writer = csv.writer(csvfile)
+ writer.writerow(headers)
+
+def outputResults(filename, n, results):
+ results.insert(0, n)
+ with open(filename, 'a') as csvfile:
+ writer = csv.writer(csvfile)
+ writer.writerow(results)
+
+def runPerf( resultDir, tests):
+ fileMap = { 'add': os.path.join(resultDir, 'add.csv'),
+ 'delete': os.path.join(resultDir, 'delete.csv'),
+ 'sync': os.path.join(resultDir, 'sync.csv') }
+ initResults(fileMap)
+ removeFlowsFromONOS(checkSwitch=False) # clear ONOS before starting
+ # start Mininet
+ topo = SingleSwitchTopo()
+ net = Mininet(topo=topo, controller=RemoteController)
+ print "Starting Mininet"
+ startNet(net)
+ wait(30, "Give ONOS 30 seconds to warm up") # let ONOS "warm-up"
+ for i in tests:
+ addFlowsToONOS(i)
+ outputResults(fileMap['sync'], i, test(i, doNothing))
+ outputResults(fileMap['delete'], i, test(i, delFlowsFromSwitch))
+ removeFlowsFromONOS()
+ outputResults(fileMap['add'], i, test(i, addFakeFlows)) # test needs empty DB
+ net.stop()
+
+if __name__ == '__main__':
+ setLogLevel( 'output' )
+ resultDir = strftime( '%Y%m%d-%H%M%S' )
+ os.mkdir( resultDir )
+ tests = sys.argv[1:]
+ if not tests:
+ tests = [1, 10, 100, 1000, 10000]
+ runPerf( resultDir, tests )
+
diff --git a/perf-scripts/generate_flows.py b/perf-scripts/generate_flows.py
new file mode 100755
index 0000000..11d9c19
--- /dev/null
+++ b/perf-scripts/generate_flows.py
@@ -0,0 +1,90 @@
+#! /usr/bin/env python
+# -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
+
+#
+# A script for generating a number of flows.
+#
+# The output of the script should be saved to a file, and the flows from
+# that file should be added by the following command:
+#
+# web/add_flow.py -f filename
+#
+# NOTE: Currently, some of the parameters fo the flows are hard-coded,
+# and all flows are between same source and destination DPID and ports
+# (differentiated by different matchSrcMac and matchDstMac).
+#
+
+import copy
+import pprint
+import os
+import sys
+import subprocess
+import json
+import argparse
+import io
+import time
+
+## Global Var ##
+
+DEBUG=0
+pp = pprint.PrettyPrinter(indent=4)
+
+## Worker Functions ##
+def log_error(txt):
+ print '%s' % (txt)
+
+def debug(txt):
+ if DEBUG:
+ print '%s' % (txt)
+
+
+if __name__ == "__main__":
+ usage_msg = "Generate a number of flows by using a pre-defined template.\n"
+ usage_msg = usage_msg + "\n"
+ usage_msg = usage_msg + "NOTE: This script is work-in-progress. Currently all flows are within same\n"
+ usage_msg = usage_msg + "pair of switch ports and contain auto-generated MAC-based matching conditions.\n"
+ usage_msg = usage_msg + "\n"
+ usage_msg = usage_msg + "Usage: %s <begin-flow-id> <end-flow-id>\n" % (sys.argv[0])
+ usage_msg = usage_msg + "\n"
+ usage_msg = usage_msg + " The output should be saved to a file, and the flows should be installed\n"
+ usage_msg = usage_msg + " by using the command './add_flow.py -f filename'\n"
+
+
+ # app.debug = False;
+
+ # Usage info
+ if len(sys.argv) > 1 and (sys.argv[1] == "-h" or sys.argv[1] == "--help"):
+ print(usage_msg)
+ exit(0)
+
+ # Check arguments
+ if len(sys.argv) < 3:
+ log_error(usage_msg)
+ exit(1)
+
+ # Extract the arguments
+ begin_flow_id = int(sys.argv[1], 0)
+ end_flow_id = int(sys.argv[2], 0)
+ if begin_flow_id > end_flow_id:
+ log_error(usage_msg)
+ exit(1)
+
+ #
+ # Do the work
+ #
+ # NOTE: Currently, up to 65536 flows are supported.
+ # More flows can be supported by iterating by, say, iterating over some of
+ # the other bytes of the autogenereated source/destination MAC addresses.
+ #
+ flow_id = begin_flow_id
+ idx = 0
+ while flow_id <= end_flow_id:
+ mac3 = idx / 255
+ mac4 = idx % 255
+ str_mac3 = "%0.2x" % mac3
+ str_mac4 = "%0.2x" % mac4
+ src_mac = "00:00:" + str_mac3 + ":" + str_mac4 + ":00:00";
+ dst_mac = "00:01:" + str_mac3 + ":" + str_mac4 + ":00:00";
+ print "%s FOOBAR 00:00:00:00:00:00:00:01 1 00:00:00:00:00:00:00:01 2 matchSrcMac %s matchDstMac %s" % (flow_id, src_mac, dst_mac)
+ flow_id = flow_id + 1
+ idx = idx + 1
diff --git a/pom.xml b/pom.xml
index a8730a5..ebed868 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,7 +31,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<powermock.version>1.5.1</powermock.version>
- <restlet.version>2.1-RC1</restlet.version>
+ <restlet.version>2.1.4</restlet.version>
<github.global.server>github</github.global.server>
</properties>
<build>
@@ -251,13 +251,11 @@
<artifactId>frames</artifactId>
<version>2.3.1</version>
</dependency>
- <!--
<dependency>
<groupId>com.tinkerpop.blueprints</groupId>
<artifactId>blueprints-core</artifactId>
<version>2.3.0</version>
</dependency>
- -->
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
@@ -292,7 +290,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
- <version>1.0.0</version>
+ <version>1.0.13</version>
<scope>runtime</scope>
</dependency>
<!-- Floodlight's dependencies -->
@@ -305,13 +303,13 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
- <version>13.0.1</version>
+ <version>14.0.1</version>
</dependency>
-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <version>1.6.4</version>
+ <version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
@@ -336,12 +334,12 @@
<dependency>
<groupId>args4j</groupId>
<artifactId>args4j</artifactId>
- <version>2.0.16</version>
+ <version>2.0.25</version>
</dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
- <version>1.3</version>
+ <version>1.4</version>
</dependency>
<!--<dependency>
<groupId>org.python</groupId>
diff --git a/setup-local-maven.sh b/setup-local-maven.sh
index 371d50f..f8e00f8 100755
--- a/setup-local-maven.sh
+++ b/setup-local-maven.sh
@@ -7,10 +7,10 @@
# Kryo2 workaround
${MVN} -f kryo2/pom.xml package exec:exec
-${MVN} install:install-file -Dfile=./lib/curator-framework-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-framework -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
-${MVN} install:install-file -Dfile=./lib/curator-client-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-client -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
-${MVN} install:install-file -Dfile=./lib/curator-recipes-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-recipes -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
-${MVN} install:install-file -Dfile=./lib/curator-x-discovery-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-x-discovery -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
+${MVN} install:install-file -Dfile=./curator/curator-framework-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-framework -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
+${MVN} install:install-file -Dfile=./curator/curator-client-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-client -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
+${MVN} install:install-file -Dfile=./curator/curator-recipes-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-recipes -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
+${MVN} install:install-file -Dfile=./curator/curator-x-discovery-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-x-discovery -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
# download package dependencies
${MVN} dependency:go-offline
diff --git a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
index 4d85b7d..67fcabb 100644
--- a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
@@ -11,7 +11,6 @@
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.storage.IStorageSourceService;
import net.floodlightcontroller.threadpool.IThreadPoolService;
@@ -47,7 +46,7 @@
Collection<Class<? extends IFloodlightService>> dependencies =
new ArrayList<Class<? extends IFloodlightService>>(4);
dependencies.add(IStorageSourceService.class);
- dependencies.add(IPktInProcessingTimeService.class);
+
dependencies.add(IRestApiService.class);
dependencies.add(ICounterStoreService.class);
dependencies.add(IThreadPoolService.class);
@@ -62,8 +61,7 @@
public void init(FloodlightModuleContext context) throws FloodlightModuleException {
controller.setStorageSourceService(
context.getServiceImpl(IStorageSourceService.class));
- controller.setPktInProcessingService(
- context.getServiceImpl(IPktInProcessingTimeService.class));
+
controller.setCounterStore(
context.getServiceImpl(ICounterStoreService.class));
controller.setRestApiService(
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 31f80cc..6b16964 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -66,7 +66,6 @@
import net.floodlightcontroller.core.web.CoreWebRoutable;
import net.floodlightcontroller.counter.ICounterStoreService;
import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.storage.IResultSet;
import net.floodlightcontroller.storage.IStorageSourceListener;
@@ -186,7 +185,6 @@
protected IRestApiService restApi;
protected ICounterStoreService counterStore = null;
protected IStorageSourceService storageSource;
- protected IPktInProcessingTimeService pktinProcTime;
protected IThreadPoolService threadPool;
protected IControllerRegistryService registryService;
@@ -394,9 +392,7 @@
this.counterStore = counterStore;
}
- public void setPktInProcessingService(IPktInProcessingTimeService pits) {
- this.pktinProcTime = pits;
- }
+
public void setRestApiService(IRestApiService restApi) {
this.restApi = restApi;
@@ -1449,8 +1445,7 @@
// Get the starting time (overall and per-component) of
// the processing chain for this packet if performance
// monitoring is turned on
- pktinProcTime.bootstrap(listeners);
- pktinProcTime.recordStartTimePktIn();
+
Command cmd;
for (IOFMessageListener listener : listeners) {
if (listener instanceof IOFSwitchFilter) {
@@ -1459,15 +1454,15 @@
}
}
- pktinProcTime.recordStartTimeComp(listener);
+
cmd = listener.receive(sw, m, bc);
- pktinProcTime.recordEndTimeComp(listener);
+
if (Command.STOP.equals(cmd)) {
break;
}
}
- pktinProcTime.recordEndTimePktIn(sw, m, bc);
+
} else {
log.warn("Unhandled OF Message: {} from {}", m, sw);
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
index 5810967..1a52418 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
@@ -49,7 +49,7 @@
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonSerialize;
-import org.codehaus.jackson.map.ser.std.ToStringSerializer;
+import org.codehaus.jackson.map.ser.ToStringSerializer;
import org.jboss.netty.channel.Channel;
import org.openflow.protocol.OFFeaturesReply;
import org.openflow.protocol.OFFeaturesRequest;
@@ -73,6 +73,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
/**
* This is the internal representation of an openflow switch.
*/
diff --git a/src/main/java/net/floodlightcontroller/core/types/MacVlanPair.java b/src/main/java/net/floodlightcontroller/core/types/MacVlanPair.java
deleted file mode 100644
index 7a44f1d..0000000
--- a/src/main/java/net/floodlightcontroller/core/types/MacVlanPair.java
+++ /dev/null
@@ -1,44 +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.core.types;
-
-public class MacVlanPair {
- public Long mac;
- public Short vlan;
- public MacVlanPair(Long mac, Short vlan) {
- this.mac = mac;
- this.vlan = vlan;
- }
-
- public long getMac() {
- return mac.longValue();
- }
-
- public short getVlan() {
- return vlan.shortValue();
- }
-
- public boolean equals(Object o) {
- return (o instanceof MacVlanPair) && (mac.equals(((MacVlanPair) o).mac))
- && (vlan.equals(((MacVlanPair) o).vlan));
- }
-
- public int hashCode() {
- return mac.hashCode() ^ vlan.hashCode();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/types/SwitchMessagePair.java b/src/main/java/net/floodlightcontroller/core/types/SwitchMessagePair.java
deleted file mode 100644
index 0e91bc9..0000000
--- a/src/main/java/net/floodlightcontroller/core/types/SwitchMessagePair.java
+++ /dev/null
@@ -1,40 +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.core.types;
-
-import org.openflow.protocol.OFMessage;
-
-import net.floodlightcontroller.core.IOFSwitch;
-
-public class SwitchMessagePair {
- private final IOFSwitch sw;
- private final OFMessage msg;
-
- public SwitchMessagePair(IOFSwitch sw, OFMessage msg) {
- this.sw = sw;
- this.msg = msg;
- }
-
- public IOFSwitch getSwitch() {
- return this.sw;
- }
-
- public OFMessage getMessage() {
- return this.msg;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java
index a014795..2eeec70 100644
--- a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java
@@ -24,8 +24,6 @@
import java.util.Map;
import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.types.MacVlanPair;
-
import org.openflow.protocol.OFFeaturesReply;
import org.openflow.protocol.statistics.OFStatistics;
import org.openflow.protocol.statistics.OFStatisticsType;
@@ -136,7 +134,6 @@
private OFStatisticsType statType;
private REQUESTTYPE requestType;
private OFFeaturesReply featuresReply;
- private Map<MacVlanPair, Short> switchTable;
public GetConcurrentStatsThread(long switchId, REQUESTTYPE requestType, OFStatisticsType statType) {
this.switchId = switchId;
@@ -144,7 +141,6 @@
this.statType = statType;
this.switchReply = null;
this.featuresReply = null;
- this.switchTable = null;
}
public List<OFStatistics> getStatisticsReply() {
@@ -155,10 +151,6 @@
return featuresReply;
}
- public Map<MacVlanPair, Short> getSwitchTable() {
- return switchTable;
- }
-
public long getSwitchId() {
return switchId;
}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java b/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java
index 725d699..7426163 100644
--- a/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java
@@ -20,7 +20,7 @@
import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
import org.codehaus.jackson.map.annotate.JsonSerialize;
-import org.codehaus.jackson.map.ser.std.ToStringSerializer;
+import org.codehaus.jackson.map.ser.ToStringSerializer;
/**
* A simple switch DPID/port pair
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index 087756c..bbeaa48 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -57,9 +57,6 @@
import net.floodlightcontroller.devicemanager.IEntityClassifierService;
import net.floodlightcontroller.devicemanager.SwitchPort;
import net.floodlightcontroller.devicemanager.web.DeviceRoutable;
-import net.floodlightcontroller.flowcache.IFlowReconcileListener;
-import net.floodlightcontroller.flowcache.IFlowReconcileService;
-import net.floodlightcontroller.flowcache.OFMatchReconcile;
import net.floodlightcontroller.packet.ARP;
import net.floodlightcontroller.packet.DHCP;
import net.floodlightcontroller.packet.Ethernet;
@@ -89,7 +86,7 @@
public class DeviceManagerImpl implements
IDeviceService, IOFMessageListener, ITopologyListener,
IFloodlightModule, IEntityClassListener,
-IFlowReconcileListener, IInfoProvider, IHAListener {
+IInfoProvider, IHAListener {
protected final static Logger logger =
LoggerFactory.getLogger(DeviceManagerImpl.class);
@@ -98,7 +95,7 @@
protected IStorageSourceService storageSource;
protected IRestApiService restApi;
protected IThreadPoolService threadPool;
- protected IFlowReconcileService flowReconcileMgr;
+
/**
* Time in milliseconds before entities will expire
@@ -601,62 +598,7 @@
return Command.CONTINUE;
}
- // ***************
- // IFlowReconcileListener
- // ***************
- @Override
- public Command reconcileFlows(ArrayList<OFMatchReconcile> ofmRcList) {
- ListIterator<OFMatchReconcile> iter = ofmRcList.listIterator();
- while (iter.hasNext()) {
- OFMatchReconcile ofm = iter.next();
-
- // Remove the STOPPed flow.
- if (Command.STOP == reconcileFlow(ofm)) {
- iter.remove();
- }
- }
-
- if (ofmRcList.size() > 0) {
- return Command.CONTINUE;
- } else {
- return Command.STOP;
- }
- }
-
- protected Command reconcileFlow(OFMatchReconcile ofm) {
- // Extract source entity information
- Entity srcEntity =
- getEntityFromFlowMod(ofm.ofmWithSwDpid, true);
- if (srcEntity == null)
- return Command.STOP;
-
- // Find the device by source entity
- Device srcDevice = findDeviceByEntity(srcEntity);
- if (srcDevice == null)
- return Command.STOP;
-
- // Store the source device in the context
- fcStore.put(ofm.cntx, CONTEXT_SRC_DEVICE, srcDevice);
-
- // Find the device matching the destination from the entity
- // classes of the source.
- Entity dstEntity = getEntityFromFlowMod(ofm.ofmWithSwDpid, false);
- Device dstDevice = null;
- if (dstEntity != null) {
- dstDevice = findDestByEntity(srcDevice, dstEntity);
- if (dstDevice != null)
- fcStore.put(ofm.cntx, CONTEXT_DST_DEVICE, dstDevice);
- }
- if (logger.isTraceEnabled()) {
- logger.trace("Reconciling flow: match={}, srcEntity={}, srcDev={}, "
- + "dstEntity={}, dstDev={}",
- new Object[] {ofm.ofmWithSwDpid.getOfMatch(),
- srcEntity, srcDevice,
- dstEntity, dstDevice } );
- }
- return Command.CONTINUE;
- }
-
+
// *****************
// IFloodlightModule
// *****************
@@ -690,7 +632,6 @@
l.add(ITopologyService.class);
l.add(IRestApiService.class);
l.add(IThreadPoolService.class);
- l.add(IFlowReconcileService.class);
l.add(IEntityClassifierService.class);
return l;
}
@@ -713,7 +654,6 @@
fmc.getServiceImpl(ITopologyService.class);
this.restApi = fmc.getServiceImpl(IRestApiService.class);
this.threadPool = fmc.getServiceImpl(IThreadPoolService.class);
- this.flowReconcileMgr = fmc.getServiceImpl(IFlowReconcileService.class);
this.entityClassifier = fmc.getServiceImpl(IEntityClassifierService.class);
}
@@ -731,7 +671,6 @@
floodlightProvider.addHAListener(this);
if (topology != null)
topology.addListener(this);
- flowReconcileMgr.addFlowReconcileListener(this);
entityClassifier.addListener(this);
Runnable ecr = new Runnable() {
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java b/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java
deleted file mode 100644
index cce3401..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-import java.util.Arrays;
-
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
-
-
-/**
- * The Class FCQueryObj.
- */
-public class FCQueryObj {
-
- /** The caller of the flow cache query. */
- public IFlowQueryHandler fcQueryHandler;
- /** The application instance name. */
- public String applInstName;
- /** The vlan Id. */
- public Short[] vlans;
- /** The destination device. */
- public IDevice dstDevice;
- /** The source device. */
- public IDevice srcDevice;
- /** The caller name */
- public String callerName;
- /** Event type that triggered this flow query submission */
- public FCQueryEvType evType;
- /** The caller opaque data. Returned unchanged in the query response
- * via the callback. The type of this object could be different for
- * different callers */
- public Object callerOpaqueObj;
-
- /**
- * Instantiates a new flow cache query object
- */
- public FCQueryObj(IFlowQueryHandler fcQueryHandler,
- String applInstName,
- Short vlan,
- IDevice srcDevice,
- IDevice dstDevice,
- String callerName,
- FCQueryEvType evType,
- Object callerOpaqueObj) {
- this.fcQueryHandler = fcQueryHandler;
- this.applInstName = applInstName;
- this.srcDevice = srcDevice;
- this.dstDevice = dstDevice;
- this.callerName = callerName;
- this.evType = evType;
- this.callerOpaqueObj = callerOpaqueObj;
-
- if (vlan != null) {
- this.vlans = new Short[] { vlan };
- } else {
- if (srcDevice != null) {
- this.vlans = srcDevice.getVlanId();
- } else if (dstDevice != null) {
- this.vlans = dstDevice.getVlanId();
- }
- }
- }
-
- @Override
- public String toString() {
- return "FCQueryObj [fcQueryCaller=" + fcQueryHandler
- + ", applInstName="
- + applInstName + ", vlans=" + Arrays.toString(vlans)
- + ", dstDevice=" + dstDevice + ", srcDevice="
- + srcDevice + ", callerName=" + callerName + ", evType="
- + evType + ", callerOpaqueObj=" + callerOpaqueObj + "]";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- FCQueryObj other = (FCQueryObj) obj;
- if (applInstName == null) {
- if (other.applInstName != null)
- return false;
- } else if (!applInstName.equals(other.applInstName))
- return false;
- if (callerName == null) {
- if (other.callerName != null)
- return false;
- } else if (!callerName.equals(other.callerName))
- return false;
- if (callerOpaqueObj == null) {
- if (other.callerOpaqueObj != null)
- return false;
- } else if (!callerOpaqueObj.equals(other.callerOpaqueObj))
- return false;
- if (dstDevice == null) {
- if (other.dstDevice != null)
- return false;
- } else if (!dstDevice.equals(other.dstDevice))
- return false;
- if (evType != other.evType)
- return false;
- if (fcQueryHandler != other.fcQueryHandler)
- return false;
- if (srcDevice == null) {
- if (other.srcDevice != null)
- return false;
- } else if (!srcDevice.equals(other.srcDevice))
- return false;
- if (!Arrays.equals(vlans, other.vlans))
- return false;
- return true;
- }
-
-
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowCacheQueryResp.java b/src/main/java/net/floodlightcontroller/flowcache/FlowCacheQueryResp.java
deleted file mode 100644
index b01aedf..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowCacheQueryResp.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-import java.util.ArrayList;
-
-/**
- * Object to return flows in response to a query message to BigFlowCache.
- * This object is passed in the flowQueryRespHandler() callback.
- */
-public class FlowCacheQueryResp {
-
- /** query object provided by the caller, returned unchanged. */
- public FCQueryObj queryObj;
- /**
- * Set to true if more flows could be returned for this query in
- * additional callbacks. Set of false in the last callback for the
- * query.
- */
- public boolean moreFlag;
-
- /**
- * Set to true if the response has been sent to handler
- */
- public boolean hasSent;
-
- /**
- * The flow list. If there are large number of flows to be returned
- * then they may be returned in multiple callbacks.
- */
- public ArrayList<QRFlowCacheObj> qrFlowCacheObjList;
-
- /**
- * Instantiates a new big flow cache query response.
- *
- * @param query the flow cache query object as given by the caller of
- * flow cache submit query API.
- */
- public FlowCacheQueryResp(FCQueryObj query) {
- qrFlowCacheObjList = new ArrayList<QRFlowCacheObj>();
- queryObj = query;
- moreFlag = false;
- hasSent = false;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- String s = queryObj.toString() + "; moreFlasg=" + moreFlag +
- "; hasSent=" + hasSent;
- s += "; FlowCount=" + Integer.toString(qrFlowCacheObjList.size());
- return s;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java
deleted file mode 100644
index b221b84..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java
+++ /dev/null
@@ -1,440 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-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.ListenerDispatcher;
-import net.floodlightcontroller.core.util.SingletonTask;
-import net.floodlightcontroller.counter.CounterStore;
-import net.floodlightcontroller.counter.ICounter;
-import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.counter.SimpleCounter;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
-import net.floodlightcontroller.flowcache.IFlowReconcileListener;
-import net.floodlightcontroller.flowcache.OFMatchReconcile;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-
-import org.openflow.protocol.OFType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FlowReconcileManager
- implements IFloodlightModule, IFlowReconcileService {
-
- /** The logger. */
- private final static Logger logger =
- LoggerFactory.getLogger(FlowReconcileManager.class);
-
- /** Reference to dependent modules */
- protected IThreadPoolService threadPool;
- protected ICounterStoreService counterStore;
-
- /**
- * The list of flow reconcile listeners that have registered to get
- * flow reconcile callbacks. Such callbacks are invoked, for example, when
- * a switch with existing flow-mods joins this controller and those flows
- * need to be reconciled with the current configuration of the controller.
- */
- protected ListenerDispatcher<OFType, IFlowReconcileListener>
- flowReconcileListeners;
-
- /** A FIFO queue to keep all outstanding flows for reconciliation */
- Queue<OFMatchReconcile> flowQueue;
-
- /** Asynchronous task to feed the flowReconcile pipeline */
- protected SingletonTask flowReconcileTask;
-
- String controllerPktInCounterName;
- protected SimpleCounter lastPacketInCounter;
-
- protected static int MAX_SYSTEM_LOAD_PER_SECOND = 50000;
- /** a minimum flow reconcile rate so that it won't stave */
- protected static int MIN_FLOW_RECONCILE_PER_SECOND = 1000;
-
- /** once per second */
- protected static int FLOW_RECONCILE_DELAY_MILLISEC = 10;
- protected Date lastReconcileTime;
-
- /** Config to enable or disable flowReconcile */
- protected static final String EnableConfigKey = "enable";
- protected boolean flowReconcileEnabled;
-
- public int flowReconcileThreadRunCount;
-
- @Override
- public synchronized void addFlowReconcileListener(
- IFlowReconcileListener listener) {
- flowReconcileListeners.addListener(OFType.FLOW_MOD, listener);
-
- if (logger.isTraceEnabled()) {
- StringBuffer sb = new StringBuffer();
- sb.append("FlowMod listeners: ");
- for (IFlowReconcileListener l :
- flowReconcileListeners.getOrderedListeners()) {
- sb.append(l.getName());
- sb.append(",");
- }
- logger.trace(sb.toString());
- }
- }
-
- @Override
- public synchronized void removeFlowReconcileListener(
- IFlowReconcileListener listener) {
- flowReconcileListeners.removeListener(listener);
- }
-
- @Override
- public synchronized void clearFlowReconcileListeners() {
- flowReconcileListeners.clearListeners();
- }
-
- /**
- * Add to-be-reconciled flow to the queue.
- *
- * @param ofmRcIn the ofm rc in
- */
- public void reconcileFlow(OFMatchReconcile ofmRcIn) {
- if (ofmRcIn == null) return;
-
- // Make a copy before putting on the queue.
- OFMatchReconcile myOfmRc = new OFMatchReconcile(ofmRcIn);
-
- flowQueue.add(myOfmRc);
-
- Date currTime = new Date();
- long delay = 0;
-
- /** schedule reconcile task immidiately if it has been more than 1 sec
- * since the last run. Otherwise, schedule the reconcile task in
- * DELAY_MILLISEC.
- */
- if (currTime.after(new Date(lastReconcileTime.getTime() + 1000))) {
- delay = 0;
- } else {
- delay = FLOW_RECONCILE_DELAY_MILLISEC;
- }
- flowReconcileTask.reschedule(delay, TimeUnit.MILLISECONDS);
-
- if (logger.isTraceEnabled()) {
- logger.trace("Reconciling flow: {}, total: {}",
- myOfmRc.toString(), flowQueue.size());
- }
- }
-
- @Override
- public void updateFlowForDestinationDevice(IDevice device,
- IFlowQueryHandler handler,
- FCQueryEvType fcEvType) {
- // NO-OP
- }
-
- @Override
- public void updateFlowForSourceDevice(IDevice device,
- IFlowQueryHandler handler,
- FCQueryEvType fcEvType) {
- // NO-OP
- }
-
- @Override
- public void flowQueryGenericHandler(FlowCacheQueryResp flowResp) {
- if (flowResp.queryObj.evType != FCQueryEvType.GET) {
- OFMatchReconcile ofmRc = new OFMatchReconcile();;
- /* Re-provision these flows */
- for (QRFlowCacheObj entry : flowResp.qrFlowCacheObjList) {
- /* reconcile the flows in entry */
- entry.toOFMatchReconcile(ofmRc,
- flowResp.queryObj.applInstName,
- OFMatchReconcile.ReconcileAction.UPDATE_PATH);
- reconcileFlow(ofmRc);
- }
- }
- return;
- }
-
- // IFloodlightModule
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFlowReconcileService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- m.put(IFlowReconcileService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>>
- getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IThreadPoolService.class);
- l.add(ICounterStoreService.class);
- return null;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- threadPool = context.getServiceImpl(IThreadPoolService.class);
- counterStore = context.getServiceImpl(ICounterStoreService.class);
-
- flowQueue = new ConcurrentLinkedQueue<OFMatchReconcile>();
- flowReconcileListeners =
- new ListenerDispatcher<OFType, IFlowReconcileListener>();
-
- Map<String, String> configParam = context.getConfigParams(this);
- String enableValue = configParam.get(EnableConfigKey);
- // Set flowReconcile default to true
- flowReconcileEnabled = true;
- if (enableValue != null &&
- enableValue.equalsIgnoreCase("false")) {
- flowReconcileEnabled = false;
- }
-
- flowReconcileThreadRunCount = 0;
- lastReconcileTime = new Date(0);
- logger.debug("FlowReconcile is {}", flowReconcileEnabled);
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- // thread to do flow reconcile
- ScheduledExecutorService ses = threadPool.getScheduledExecutor();
- flowReconcileTask = new SingletonTask(ses, new Runnable() {
- @Override
- public void run() {
- try {
- if (doReconcile()) {
- flowReconcileTask.reschedule(
- FLOW_RECONCILE_DELAY_MILLISEC,
- TimeUnit.MILLISECONDS);
- }
- } catch (Exception e) {
- logger.warn("Exception in doReconcile(): {}",
- e.getMessage());
- e.printStackTrace();
- }
- }
- });
-
- String packetInName = OFType.PACKET_IN.toClass().getName();
- packetInName = packetInName.substring(packetInName.lastIndexOf('.')+1);
-
- // Construct controller counter for the packet_in
- controllerPktInCounterName =
- CounterStore.createCounterName(ICounterStoreService.CONTROLLER_NAME,
- -1,
- packetInName);
- }
-
- /**
- * Feed the flows into the flow reconciliation pipeline.
- * @return true if more flows to be reconciled
- * false if no more flows to be reconciled.
- */
- protected boolean doReconcile() {
- if (!flowReconcileEnabled) {
- return false;
- }
-
- // Record the execution time.
- lastReconcileTime = new Date();
-
- ArrayList<OFMatchReconcile> ofmRcList =
- new ArrayList<OFMatchReconcile>();
-
- // Get the maximum number of flows that can be reconciled.
- int reconcileCapacity = getCurrentCapacity();
- if (logger.isTraceEnabled()) {
- logger.trace("Reconcile capacity {} flows", reconcileCapacity);
- }
- while (!flowQueue.isEmpty() && reconcileCapacity > 0) {
- OFMatchReconcile ofmRc = flowQueue.poll();
- reconcileCapacity--;
- if (ofmRc != null) {
- ofmRcList.add(ofmRc);
- if (logger.isTraceEnabled()) {
- logger.trace("Add flow {} to be the reconcileList", ofmRc.cookie);
- }
- } else {
- break;
- }
- }
-
- // Run the flow through all the flow reconcile listeners
- IFlowReconcileListener.Command retCmd;
- if (ofmRcList.size() > 0) {
- List<IFlowReconcileListener> listeners =
- flowReconcileListeners.getOrderedListeners();
- if (listeners == null) {
- if (logger.isTraceEnabled()) {
- logger.trace("No flowReconcile listener");
- }
- return false;
- }
-
- for (IFlowReconcileListener flowReconciler :
- flowReconcileListeners.getOrderedListeners()) {
- if (logger.isTraceEnabled()) {
- logger.trace("Reconciling flow: call listener {}",
- flowReconciler.getName());
- }
- retCmd = flowReconciler.reconcileFlows(ofmRcList);
- if (retCmd == IFlowReconcileListener.Command.STOP) {
- break;
- }
- }
- flowReconcileThreadRunCount++;
- } else {
- if (logger.isTraceEnabled()) {
- logger.trace("No flow to be reconciled.");
- }
- }
-
- // Return true if there are more flows to be reconciled
- if (flowQueue.isEmpty()) {
- return false;
- } else {
- if (logger.isTraceEnabled()) {
- logger.trace("{} more flows to be reconciled.",
- flowQueue.size());
- }
- return true;
- }
- }
-
- /**
- * Compute the maximum number of flows to be reconciled.
- *
- * It computes the packetIn increment from the counter values in
- * the counter store;
- * Then computes the rate based on the elapsed time
- * from the last query;
- * Then compute the max flow reconcile rate by subtracting the packetIn
- * rate from the hard-coded max system rate.
- * If the system rate is reached or less than MIN_FLOW_RECONCILE_PER_SECOND,
- * set the maximum flow reconcile rate to the MIN_FLOW_RECONCILE_PER_SECOND
- * to prevent starvation.
- * Then convert the rate to an absolute number for the
- * FLOW_RECONCILE_PERIOD.
- * @return
- */
- protected int getCurrentCapacity() {
- ICounter pktInCounter =
- counterStore.getCounter(controllerPktInCounterName);
- int minFlows = MIN_FLOW_RECONCILE_PER_SECOND *
- FLOW_RECONCILE_DELAY_MILLISEC / 1000;
-
- // If no packetInCounter, then there shouldn't be any flow.
- if (pktInCounter == null ||
- pktInCounter.getCounterDate() == null ||
- pktInCounter.getCounterValue() == null) {
- logger.debug("counter {} doesn't exist",
- controllerPktInCounterName);
- return minFlows;
- }
-
- // Haven't get any counter yet.
- if (lastPacketInCounter == null) {
- logger.debug("First time get the count for {}",
- controllerPktInCounterName);
- lastPacketInCounter = (SimpleCounter)
- SimpleCounter.createCounter(pktInCounter);
- return minFlows;
- }
-
- int pktInRate = getPktInRate(pktInCounter, new Date());
-
- // Update the last packetInCounter
- lastPacketInCounter = (SimpleCounter)
- SimpleCounter.createCounter(pktInCounter);
- int capacity = minFlows;
- if ((pktInRate + MIN_FLOW_RECONCILE_PER_SECOND) <=
- MAX_SYSTEM_LOAD_PER_SECOND) {
- capacity = (MAX_SYSTEM_LOAD_PER_SECOND - pktInRate)
- * FLOW_RECONCILE_DELAY_MILLISEC / 1000;
- }
-
- if (logger.isTraceEnabled()) {
- logger.trace("Capacity is {}", capacity);
- }
- return capacity;
- }
-
- protected int getPktInRate(ICounter newCnt, Date currentTime) {
- if (newCnt == null ||
- newCnt.getCounterDate() == null ||
- newCnt.getCounterValue() == null) {
- return 0;
- }
-
- // Somehow the system time is messed up. return max packetIn rate
- // to reduce the system load.
- if (newCnt.getCounterDate().before(
- lastPacketInCounter.getCounterDate())) {
- logger.debug("Time is going backward. new {}, old {}",
- newCnt.getCounterDate(),
- lastPacketInCounter.getCounterDate());
- return MAX_SYSTEM_LOAD_PER_SECOND;
- }
-
- long elapsedTimeInSecond = (currentTime.getTime() -
- lastPacketInCounter.getCounterDate().getTime()) / 1000;
- if (elapsedTimeInSecond == 0) {
- // This should never happen. Check to avoid division by zero.
- return 0;
- }
-
- long diff = 0;
- switch (newCnt.getCounterValue().getType()) {
- case LONG:
- long newLong = newCnt.getCounterValue().getLong();
- long oldLong = lastPacketInCounter.getCounterValue().getLong();
- if (newLong < oldLong) {
- // Roll over event
- diff = Long.MAX_VALUE - oldLong + newLong;
- } else {
- diff = newLong - oldLong;
- }
- break;
-
- case DOUBLE:
- double newDouble = newCnt.getCounterValue().getDouble();
- double oldDouble = lastPacketInCounter.getCounterValue().getDouble();
- if (newDouble < oldDouble) {
- // Roll over event
- diff = (long)(Double.MAX_VALUE - oldDouble + newDouble);
- } else {
- diff = (long)(newDouble - oldDouble);
- }
- break;
- }
-
- return (int)(diff/elapsedTimeInSecond);
- }
-}
-
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java
deleted file mode 100644
index 8e44ed3..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-import org.openflow.protocol.OFMatchWithSwDpid;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.FloodlightContextStore;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-/**
- * The Interface IFlowCache.
- * <p>
- * public interface APIs to Big Switch Flow-Cache Service. Flow-Cache maintains
- * the network-level flows that are currently deployed in the underlying
- * network. The flow cache can be queried using various filters by using the
- * corresponding APIs.
- *
- * @author subrata
- *
- */
-public interface IFlowCacheService extends IFloodlightService {
-
- public static final String FLOWCACHE_APP_NAME =
- "net.floodlightcontroller.flowcache.appName";
- public static final String FLOWCACHE_APP_INSTANCE_NAME =
- "net.floodlightcontroller.flowcache.appInstanceName";
-
- /**
- * The flow cache query event type indicating the event that triggered the
- * query. The callerOpaqueObj can be keyed based on this event type
- */
- public static enum FCQueryEvType {
- /** The GET query. Flows need not be reconciled for this query type */
- GET,
- /** A new App was added. */
- APP_ADDED,
- /** An App was deleted. */
- APP_DELETED,
- /** Interface rule of an app was modified */
- APP_INTERFACE_RULE_CHANGED,
- /** Some App configuration was changed */
- APP_CONFIG_CHANGED,
- /** An ACL was added */
- ACL_ADDED,
- /** An ACL was deleted */
- ACL_DELETED,
- /** An ACL rule was added */
- ACL_RULE_ADDED,
- /** An ACL rule was deleted */
- ACL_RULE_DELETED,
- /** ACL configuration was changed */
- ACL_CONFIG_CHANGED,
- /** device had moved to a different port in the network */
- DEVICE_MOVED,
- /** device's property had changed, such as tag assignment */
- DEVICE_PROPERTY_CHANGED,
- /** Link down */
- LINK_DOWN,
- /** Periodic scan of switch flow table */
- PERIODIC_SCAN,
- }
-
- /**
- * A FloodlightContextStore object that can be used to interact with the
- * FloodlightContext information about flowCache.
- */
- public static final FloodlightContextStore<String> fcStore =
- new FloodlightContextStore<String>();
-
- /**
- * Submit a flow cache query with query parameters specified in FCQueryObj
- * object. The query object can be created using one of the newFCQueryObj
- * helper functions in IFlowCache interface.
- * <p>
- * The queried flows are returned via the flowQueryRespHandler() callback
- * that the caller must implement. The caller can match the query with
- * the response using unique callerOpaqueData which remains unchanged
- * in the request and response callback.
- *
- * @see com.bigswitch.floodlight.flowcache#flowQueryRespHandler
- * @param query the flow cache query object as input
- *
- */
- public void submitFlowCacheQuery(FCQueryObj query);
-
- /**
- * Deactivates all flows in the flow cache for which the source switch
- * matches the given switchDpid. Note that the flows are NOT deleted
- * from the cache.
- *
- * @param switchDpid Data-path identifier of the source switch
- */
- public void deactivateFlowCacheBySwitch(long switchDpid);
-
- /**
- * Deletes all flows in the flow cache for which the source switch
- * matches the given switchDpid.
- *
- * @param switchDpid Data-path identifier of the source switch
- */
- public void deleteFlowCacheBySwitch(long switchDpid);
-
- /**
- * Add a flow to the flow-cache - called when a flow-mod is about to be
- * written to a set of switches. If it returns false then it should not
- * be written to the switches. If it returns true then the cookie returned
- * should be used for the flow mod sent to the switches.
- *
- * @param appInstName Application instance name
- * @param ofm openflow match object
- * @param cookie openflow-mod cookie
- * @param swPort SwitchPort object
- * @param priority openflow match priority
- * @param action action taken on the matched packets (PERMIT or DENY)
- * @return true: flow should be written to the switch(es)
- * false: flow should not be written to the switch(es). false is
- * returned, for example, when the flow was recently
- * written to the flow-cache and hence it is dampened to
- * avoid frequent writes of the same flow to the switches
- * This case can typically arise for the flows written at the
- * internal ports as they are heavily wild-carded.
- */
- public boolean addFlow(String appInstName, OFMatchWithSwDpid ofm,
- Long cookie, long srcSwDpid,
- short inPort, short priority, byte action);
-
- /**
- * Add a flow to the flow-cache - called when a flow-mod is about to be
- * written to a set of switches. If it returns false then it should not
- * be written to the switches. If it returns true then the cookie returned
- * should be used for the flow mod sent to the switches.
- *
- * @param cntx the cntx
- * @param ofm the ofm
- * @param cookie the cookie
- * @param swPort the sw port
- * @param priority the priority
- * @param action the action
- * @return true: flow should be written to the switch(es)
- * false: flow should not be written to the switch(es). false is
- * returned, for example, when the flow was recently
- * written to the flow-cache and hence it is dampened to
- * avoid frequent writes of the same flow to the switches
- * This case can typically arise for the flows written at the
- * internal ports as they are heavily wild-carded.
- */
- public boolean addFlow(FloodlightContext cntx, OFMatchWithSwDpid ofm,
- Long cookie, SwitchPort swPort,
- short priority, byte action);
-
- /**
- * Move the specified flow from its current application instance to a
- * different application instance. This API can be used when a flow moves
- * to a different application instance when the application instance
- * configuration changes or when a device moves to a different part in
- * the network that belongs to a different application instance.
- * <p>
- * Note that, if the flow was not found in the current application
- * instance then the flow is not moved to the new application instance.
- *
- * @param ofMRc the object containing the flow match and new application
- * instance name.
- * @return true is the flow was found in the flow cache in the current
- * application instance; false if the flow was not found in the flow-cache
- * in the current application instance.
- */
- public boolean moveFlowToDifferentApplInstName(OFMatchReconcile ofMRc);
-
- /**
- * Delete all flow from the specified switch
- * @param sw
- */
- public void deleteAllFlowsAtASourceSwitch(IOFSwitch sw);
-
- /**
- * Post a request to update flowcache from a switch.
- * This is an asynchronous operation.
- * It queries the switch for stats and updates the flowcache asynchronously
- * with the response.
- * @param swDpid
- * @param delay_ms
- */
- public void querySwitchFlowTable(long swDpid);
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowQueryHandler.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowQueryHandler.java
deleted file mode 100644
index 5d1b1a9..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowQueryHandler.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-public interface IFlowQueryHandler {
- /**
- * This callback function is called in response to a flow query request
- * submitted to the flow cache service. The module handling this callback
- * can be different from the one that submitted the query. In the flow
- * query object used for submitting the flow query, the identity of the
- * callback handler is passed. When flow cache service has all or some
- * of the flows that needs to be returned then this callback is called
- * for the appropriate module. The respone contains a boolean more flag
- * that indicates if there are additional flows that may be returned
- * via additional callback calls.
- *
- * @param resp the response object containing the original flow query
- * object, partial or complete list of flows that we queried and some
- * metadata such as the more flag described aboce.
- *
- */
- public void flowQueryRespHandler(FlowCacheQueryResp resp);
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileListener.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileListener.java
deleted file mode 100644
index f1100ed..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileListener.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-import java.util.ArrayList;
-
-import net.floodlightcontroller.core.IListener;
-import org.openflow.protocol.OFType;
-
-/**
- * The Interface IFlowReconciler.
- *
- * @author subrata
- */
-public interface IFlowReconcileListener extends IListener<OFType> {
- /**
- * Given an input OFMatch, this method applies the policy of the reconciler
- * and returns a the same input OFMatch structure modified. Additional
- * OFMatches, if needed, are returned in OFMatch-list. All the OFMatches
- * are assumed to have "PERMIT" action.
- *
- * @param ofmRcList input flow matches, to be updated to be consistent with
- * the policies of this reconciler
- * Additional OFMatch-es can be added to the "list" as
- * needed.
- * For example after a new ACL application, one flow-match
- * may result in multiple flow-matches
- * The method must also update the ReconcileAction
- * member in ofmRcList entries to indicate if the
- * flow needs to be modified, deleted or left unchanged
- * OR of a new entry is to be added after flow
- * reconciliation
- *
- *
- * @return Command.CONTINUE if the OFMatch should be sent to the
- * next flow reconciler.
- * Command.STOP if the OFMatch shouldn't be processed
- * further. In this case the no reconciled flow-mods would
- * be programmed
- */
- public Command reconcileFlows(ArrayList<OFMatchReconcile> ofmRcList);
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java
deleted file mode 100644
index f48c4e0..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Provides Flow Reconcile service to other modules that need to reconcile
- * flows.
- */
-package net.floodlightcontroller.flowcache;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
-
-public interface IFlowReconcileService extends IFloodlightService {
- /**
- * Add a flow reconcile listener
- * @param listener The module that can reconcile flows
- */
- public void addFlowReconcileListener(IFlowReconcileListener listener);
-
- /**
- * Remove a flow reconcile listener
- * @param listener The module that no longer reconcile flows
- */
- public void removeFlowReconcileListener(IFlowReconcileListener listener);
-
- /**
- * Remove all flow reconcile listeners
- */
- public void clearFlowReconcileListeners();
-
- /**
- * Reconcile flow. Returns false if no modified flow-mod need to be
- * programmed if cluster ID is providced then pnly flows in the given
- * cluster are reprogrammed
- *
- * @param ofmRcIn the ofm rc in
- */
- public void reconcileFlow(OFMatchReconcile ofmRcIn);
-
- /**
- * Updates the flows to a device after the device moved to a new location
- * <p>
- * Queries the flow-cache to get all the flows destined to the given device.
- * Reconciles each of these flows by potentially reprogramming them to its
- * new attachment point
- *
- * @param device device that has moved
- * @param handler handler to process the flows
- * @param fcEvType Event type that triggered the update
- *
- */
- public void updateFlowForDestinationDevice(IDevice device,
- IFlowQueryHandler handler,
- FCQueryEvType fcEvType);
-
- /**
- * Updates the flows from a device
- * <p>
- * Queries the flow-cache to get all the flows source from the given device.
- * Reconciles each of these flows by potentially reprogramming them to its
- * new attachment point
- *
- * @param device device where the flow originates
- * @param handler handler to process the flows
- * @param fcEvType Event type that triggered the update
- *
- */
- public void updateFlowForSourceDevice(IDevice device,
- IFlowQueryHandler handler,
- FCQueryEvType fcEvType);
-
- /**
- * Generic flow query handler to insert FlowMods into the reconcile pipeline.
- * @param flowResp
- */
- public void flowQueryGenericHandler(FlowCacheQueryResp flowResp);
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/OFMatchReconcile.java b/src/main/java/net/floodlightcontroller/flowcache/OFMatchReconcile.java
deleted file mode 100644
index 68831f4..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/OFMatchReconcile.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import org.openflow.protocol.OFMatchWithSwDpid;
-
-/**
- * OFMatchReconcile class to indicate result of a flow-reconciliation.
- */
-public class OFMatchReconcile {
-
- /**
- * The enum ReconcileAction. Specifies the result of reconciliation of a
- * flow.
- */
- public enum ReconcileAction {
-
- /** Delete the flow-mod from the switch */
- DROP,
- /** Leave the flow-mod as-is. */
- NO_CHANGE,
- /** Program this new flow mod. */
- NEW_ENTRY,
- /**
- * Reprogram the flow mod as the path of the flow might have changed,
- * for example when a host is moved or when a link goes down. */
- UPDATE_PATH,
- /* Flow is now in a different BVS */
- APP_INSTANCE_CHANGED,
- /* Delete the flow-mod - used to delete, for example, drop flow-mods
- * when the source and destination are in the same BVS after a
- * configuration change */
- DELETE
- }
-
- /** The open flow match after reconciliation. */
- public OFMatchWithSwDpid ofmWithSwDpid;
- /** flow mod. priority */
- public short priority;
- /** Action of this flow-mod PERMIT or DENY */
- public byte action;
- /** flow mod. cookie */
- public long cookie;
- /** The application instance name. */
- public String appInstName;
- /**
- * The new application instance name. This is null unless the flow
- * has moved to a different BVS due to BVS config change or device
- * move to a different switch port etc.*/
- public String newAppInstName;
- /** The reconcile action. */
- public ReconcileAction rcAction;
-
- // The context for the reconcile action
- public FloodlightContext cntx;
-
- /**
- * Instantiates a new oF match reconcile object.
- */
- public OFMatchReconcile() {
- ofmWithSwDpid = new OFMatchWithSwDpid();
- rcAction = ReconcileAction.NO_CHANGE;
- cntx = new FloodlightContext();
- }
-
- public OFMatchReconcile(OFMatchReconcile copy) {
- ofmWithSwDpid =
- new OFMatchWithSwDpid(copy.ofmWithSwDpid.getOfMatch(),
- copy.ofmWithSwDpid.getSwitchDataPathId());
- priority = copy.priority;
- action = copy.action;
- cookie = copy.cookie;
- appInstName = copy.appInstName;
- newAppInstName = copy.newAppInstName;
- rcAction = copy.rcAction;
- cntx = new FloodlightContext();
- }
-
- @Override
- public String toString() {
- return "OFMatchReconcile [" + ofmWithSwDpid + " priority=" + priority + " action=" + action +
- " cookie=" + cookie + " appInstName=" + appInstName + " newAppInstName=" + newAppInstName +
- " ReconcileAction=" + rcAction + "]";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/PendingSwRespKey.java b/src/main/java/net/floodlightcontroller/flowcache/PendingSwRespKey.java
deleted file mode 100644
index 767ce94..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/PendingSwRespKey.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-public class PendingSwRespKey {
- long swDpid;
- int transId;
-
- public PendingSwRespKey(long swDpid, int transId) {
- this.swDpid = swDpid;
- this.transId = transId;
- }
-
- @Override
- public int hashCode() {
- final int prime = 97;
- Long dpid = swDpid;
- Integer tid = transId;
- return (tid.hashCode()*prime + dpid.hashCode());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof PendingSwRespKey)) {
- return false;
- }
- PendingSwRespKey other = (PendingSwRespKey) obj;
- if ((swDpid != other.swDpid) || (transId != other.transId)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return Long.toHexString(swDpid)+","+Integer.toString(transId);
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/PendingSwitchResp.java b/src/main/java/net/floodlightcontroller/flowcache/PendingSwitchResp.java
deleted file mode 100644
index d6f264f..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/PendingSwitchResp.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
-
-/**
- * The Class PendingSwitchResp. This object is used to track the pending
- * responses to switch flow table queries.
- */
-public class PendingSwitchResp {
- protected FCQueryEvType evType;
-
- public PendingSwitchResp(
- FCQueryEvType evType) {
- this.evType = evType;
- }
-
- public FCQueryEvType getEvType() {
- return evType;
- }
-
- public void setEvType(FCQueryEvType evType) {
- this.evType = evType;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/QRFlowCacheObj.java b/src/main/java/net/floodlightcontroller/flowcache/QRFlowCacheObj.java
deleted file mode 100644
index 5121f8b..0000000
--- a/src/main/java/net/floodlightcontroller/flowcache/QRFlowCacheObj.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-
-import org.openflow.protocol.OFMatchWithSwDpid;
-
-/**
- * Used in BigFlowCacheQueryResp as query result.
- * Used to return one flow when queried by one of the big flow cache APIs.
- * One of these QRFlowCacheObj is returned for each combination of
- * priority and action.
- *
- * @author subrata
- */
-public class QRFlowCacheObj {
-
- /** The open flow match object. */
- public OFMatchWithSwDpid ofmWithSwDpid;
- /** The flow-mod priority. */
- public short priority;
- /** flow-mod cookie */
- public long cookie;
- /** The action - PERMIT or DENY. */
- public byte action;
- /** The reserved byte to align with 8 bytes. */
- public byte reserved;
-
- /**
- * Instantiates a new flow cache query object.
- *
- * @param priority the priority
- * @param action the action
- */
- public QRFlowCacheObj(short priority, byte action, long cookie) {
- ofmWithSwDpid = new OFMatchWithSwDpid();
- this.action = action;
- this.priority = priority;
- this.cookie = cookie;
- }
-
- /**
- * Populate a given OFMatchReconcile object from the values of this
- * class.
- *
- * @param ofmRc the given OFMatchReconcile object
- * @param appInstName the application instance name
- * @param rcAction the reconcile action
- */
- public void toOFMatchReconcile(OFMatchReconcile ofmRc,
- String appInstName, OFMatchReconcile.ReconcileAction rcAction) {
- ofmRc.ofmWithSwDpid = ofmWithSwDpid; // not copying
- ofmRc.appInstName = appInstName;
- ofmRc.rcAction = rcAction;
- ofmRc.priority = priority;
- ofmRc.cookie = cookie;
- ofmRc.action = action;
- }
-
- @Override
- public String toString() {
- String str = "ofmWithSwDpid: " + this.ofmWithSwDpid.toString() + " ";
- str += "priority: " + this.priority + " ";
- str += "cookie: " + this.cookie + " ";
- str += "action: " + this.action + " ";
- str += "reserved: " + this.reserved + " ";
- return str;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java
deleted file mode 100644
index e76253d..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package net.floodlightcontroller.perfmon;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-
-import net.floodlightcontroller.core.IOFMessageListener;
-
-@JsonSerialize(using=CumulativeTimeBucketJSONSerializer.class)
-public class CumulativeTimeBucket {
- private long startTime_ns; // First pkt time-stamp in this bucket
- private Map<Integer, OneComponentTime> compStats;
- private long totalPktCnt;
- private long totalProcTimeNs; // total processing time for one pkt in
- private long sumSquaredProcTimeNs2;
- private long maxTotalProcTimeNs;
- private long minTotalProcTimeNs;
- private long avgTotalProcTimeNs;
- private long sigmaTotalProcTimeNs; // std. deviation
-
- public long getStartTimeNs() {
- return startTime_ns;
- }
-
- public long getTotalPktCnt() {
- return totalPktCnt;
- }
-
- public long getAverageProcTimeNs() {
- return avgTotalProcTimeNs;
- }
-
- public long getMinTotalProcTimeNs() {
- return minTotalProcTimeNs;
- }
-
- public long getMaxTotalProcTimeNs() {
- return maxTotalProcTimeNs;
- }
-
- public long getTotalSigmaProcTimeNs() {
- return sigmaTotalProcTimeNs;
- }
-
- public int getNumComps() {
- return compStats.values().size();
- }
-
- public Collection<OneComponentTime> getModules() {
- return compStats.values();
- }
-
- public CumulativeTimeBucket(List<IOFMessageListener> listeners) {
- compStats = new ConcurrentHashMap<Integer, OneComponentTime>(listeners.size());
- for (IOFMessageListener l : listeners) {
- OneComponentTime oct = new OneComponentTime(l);
- compStats.put(oct.hashCode(), oct);
- }
- startTime_ns = System.nanoTime();
- }
-
- private void updateSquaredProcessingTime(long curTimeNs) {
- sumSquaredProcTimeNs2 += (Math.pow(curTimeNs, 2));
- }
-
- /**
- * Resets all counters and counters for each component time
- */
- public void reset() {
- startTime_ns = System.nanoTime();
- totalPktCnt = 0;
- totalProcTimeNs = 0;
- avgTotalProcTimeNs = 0;
- sumSquaredProcTimeNs2 = 0;
- maxTotalProcTimeNs = Long.MIN_VALUE;
- minTotalProcTimeNs = Long.MAX_VALUE;
- sigmaTotalProcTimeNs = 0;
- for (OneComponentTime oct : compStats.values()) {
- oct.resetAllCounters();
- }
- }
-
- private void computeSigma() {
- // Computes std. deviation from the sum of count numbers and from
- // the sum of the squares of count numbers
- double temp = totalProcTimeNs;
- temp = Math.pow(temp, 2) / totalPktCnt;
- temp = (sumSquaredProcTimeNs2 - temp) / totalPktCnt;
- sigmaTotalProcTimeNs = (long) Math.sqrt(temp);
- }
-
- public void computeAverages() {
- // Must be called last to, needs latest info
- computeSigma();
-
- for (OneComponentTime oct : compStats.values()) {
- oct.computeSigma();
- }
- }
-
- public void updatePerPacketCounters(long procTimeNs) {
- totalPktCnt++;
- totalProcTimeNs += procTimeNs;
- avgTotalProcTimeNs = totalProcTimeNs / totalPktCnt;
- updateSquaredProcessingTime(procTimeNs);
-
- if (procTimeNs > maxTotalProcTimeNs) {
- maxTotalProcTimeNs = procTimeNs;
- }
-
- if (procTimeNs < minTotalProcTimeNs) {
- minTotalProcTimeNs = procTimeNs;
- }
- }
-
- public void updateOneComponent(IOFMessageListener l, long procTimeNs) {
- compStats.get(l.hashCode()).updatePerPacketCounters(procTimeNs);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucketJSONSerializer.java b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucketJSONSerializer.java
deleted file mode 100644
index e492777..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucketJSONSerializer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.floodlightcontroller.perfmon;
-
-import java.io.IOException;
-import java.sql.Timestamp;
-
-
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.map.JsonSerializer;
-import org.codehaus.jackson.map.SerializerProvider;
-
-public class CumulativeTimeBucketJSONSerializer
- extends JsonSerializer<CumulativeTimeBucket> {
- /**
- * Performs the serialization of a OneComponentTime object
- */
- @Override
- public void serialize(CumulativeTimeBucket ctb,
- JsonGenerator jGen,
- SerializerProvider serializer)
- throws IOException, JsonProcessingException {
- jGen.writeStartObject();
- Timestamp ts = new Timestamp(ctb.getStartTimeNs()/1000000);
- jGen.writeStringField("start-time", ts.toString());
- jGen.writeStringField("current-time",
- new Timestamp(System.currentTimeMillis()).toString());
- jGen.writeNumberField("total-packets", ctb.getTotalPktCnt());
- jGen.writeNumberField("average", ctb.getAverageProcTimeNs());
- jGen.writeNumberField("min", ctb.getMinTotalProcTimeNs());
- jGen.writeNumberField("max", ctb.getMaxTotalProcTimeNs());
- jGen.writeNumberField("std-dev", ctb.getTotalSigmaProcTimeNs());
- jGen.writeArrayFieldStart("modules");
- for (OneComponentTime oct : ctb.getModules()) {
- serializer.defaultSerializeValue(oct, jGen);
- }
- jGen.writeEndArray();
- jGen.writeEndObject();
- }
-
- /**
- * Tells SimpleModule that we are the serializer for OFMatch
- */
- @Override
- public Class<CumulativeTimeBucket> handledType() {
- return CumulativeTimeBucket.class;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/perfmon/IPktInProcessingTimeService.java b/src/main/java/net/floodlightcontroller/perfmon/IPktInProcessingTimeService.java
deleted file mode 100644
index 80dfda0..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/IPktInProcessingTimeService.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package net.floodlightcontroller.perfmon;
-
-import java.util.List;
-
-import org.openflow.protocol.OFMessage;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IPktInProcessingTimeService extends IFloodlightService {
-
- /**
- * Creates time buckets for a set of modules to measure their performance
- * @param listeners The message listeners to create time buckets for
- */
- public void bootstrap(List<IOFMessageListener> listeners);
-
- /**
- * Stores a timestamp in ns. Used right before a service handles an
- * OF message. Only stores if the service is enabled.
- */
- public void recordStartTimeComp(IOFMessageListener listener);
-
- public void recordEndTimeComp(IOFMessageListener listener);
-
- public void recordStartTimePktIn();
-
- public void recordEndTimePktIn(IOFSwitch sw, OFMessage m, FloodlightContext cntx);
-
- public boolean isEnabled();
-
- public void setEnabled(boolean enabled);
-
- public CumulativeTimeBucket getCtb();
-}
diff --git a/src/main/java/net/floodlightcontroller/perfmon/NullPktInProcessingTime.java b/src/main/java/net/floodlightcontroller/perfmon/NullPktInProcessingTime.java
deleted file mode 100644
index 3d9504b..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/NullPktInProcessingTime.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package net.floodlightcontroller.perfmon;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.openflow.protocol.OFMessage;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-/**
- * An IPktInProcessingTimeService implementation that does nothing.
- * This is used mainly for performance testing or if you don't
- * want to use the IPktInProcessingTimeService features.
- * @author alexreimers
- *
- */
-public class NullPktInProcessingTime
- implements IFloodlightModule, IPktInProcessingTimeService {
-
- private CumulativeTimeBucket ctb;
- private boolean inited = false;
-
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IPktInProcessingTimeService.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(IPktInProcessingTimeService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- // We don't have any dependencies
- return null;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
-
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- // no-op
- }
-
- @Override
- public boolean isEnabled() {
- return false;
- }
-
- @Override
- public void bootstrap(List<IOFMessageListener> listeners) {
- if (!inited)
- ctb = new CumulativeTimeBucket(listeners);
- }
-
- @Override
- public void recordStartTimeComp(IOFMessageListener listener) {
-
- }
-
- @Override
- public void recordEndTimeComp(IOFMessageListener listener) {
-
- }
-
- @Override
- public void recordStartTimePktIn() {
-
- }
-
- @Override
- public void recordEndTimePktIn(IOFSwitch sw, OFMessage m,
- FloodlightContext cntx) {
-
- }
-
- @Override
- public void setEnabled(boolean enabled) {
-
- }
-
- @Override
- public CumulativeTimeBucket getCtb() {
- return ctb;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java b/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java
deleted file mode 100644
index 3e9734b..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package net.floodlightcontroller.perfmon;
-
-import org.codehaus.jackson.annotate.JsonProperty;
-
-import net.floodlightcontroller.core.IOFMessageListener;
-
-/**
- * Holds OF message processing time information for one IFloodlightModule.
- * @author Subrata
- */
-public class OneComponentTime {
- private int compId; // hascode of IOFMessageListener
- private String compName;
- private int pktCnt;
- // all times in nanoseconds
- private long totalProcTimeNs;
- private long sumSquaredProcTimeNs2; // squared
- private long maxProcTimeNs;
- private long minProcTimeNs;
- private long avgProcTimeNs;
- private long sigmaProcTimeNs; // std. deviation
-
- public OneComponentTime(IOFMessageListener module) {
- compId = module.hashCode();
- compName = module.getClass().getCanonicalName();
- resetAllCounters();
- }
-
- public void resetAllCounters() {
- maxProcTimeNs = Long.MIN_VALUE;
- minProcTimeNs = Long.MAX_VALUE;
- pktCnt = 0;
- totalProcTimeNs = 0;
- sumSquaredProcTimeNs2 = 0;
- avgProcTimeNs = 0;
- sigmaProcTimeNs = 0;
- }
-
- @JsonProperty("module-name")
- public String getCompName() {
- return compName;
- }
-
- @JsonProperty("num-packets")
- public int getPktCnt() {
- return pktCnt;
- }
-
- @JsonProperty("total")
- public long getSumProcTimeNs() {
- return totalProcTimeNs;
- }
-
- @JsonProperty("max")
- public long getMaxProcTimeNs() {
- return maxProcTimeNs;
- }
-
- @JsonProperty("min")
- public long getMinProcTimeNs() {
- return minProcTimeNs;
- }
-
- @JsonProperty("average")
- public long getAvgProcTimeNs() {
- return avgProcTimeNs;
- }
-
- @JsonProperty("std-dev")
- public long getSigmaProcTimeNs() {
- return sigmaProcTimeNs;
- }
-
- @JsonProperty("average-squared")
- public long getSumSquaredProcTimeNs() {
- return sumSquaredProcTimeNs2;
- }
-
- // Methods used to update the counters
-
- private void increasePktCount() {
- pktCnt++;
- }
-
- private void updateTotalProcessingTime(long procTimeNs) {
- totalProcTimeNs += procTimeNs;
- }
-
- private void updateAvgProcessTime() {
- avgProcTimeNs = totalProcTimeNs / pktCnt;
- }
-
- private void updateSquaredProcessingTime(long procTimeNs) {
- sumSquaredProcTimeNs2 += (Math.pow(procTimeNs, 2));
- }
-
- private void calculateMinProcTime(long curTimeNs) {
- if (curTimeNs < minProcTimeNs)
- minProcTimeNs = curTimeNs;
- }
-
- private void calculateMaxProcTime(long curTimeNs) {
- if (curTimeNs > maxProcTimeNs)
- maxProcTimeNs = curTimeNs;
- }
-
- public void computeSigma() {
- // Computes std. deviation from the sum of count numbers and from
- // the sum of the squares of count numbers
- double temp = totalProcTimeNs;
- temp = Math.pow(temp, 2) / pktCnt;
- temp = (sumSquaredProcTimeNs2 - temp) / pktCnt;
- sigmaProcTimeNs = (long) Math.sqrt(temp);
- }
-
- public void updatePerPacketCounters(long procTimeNs) {
- increasePktCount();
- updateTotalProcessingTime(procTimeNs);
- calculateMinProcTime(procTimeNs);
- calculateMaxProcTime(procTimeNs);
- updateAvgProcessTime();
- updateSquaredProcessingTime(procTimeNs);
- }
-
- @Override
- public int hashCode() {
- return compId;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/perfmon/PerfMonDataResource.java b/src/main/java/net/floodlightcontroller/perfmon/PerfMonDataResource.java
deleted file mode 100644
index 297c44e..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/PerfMonDataResource.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package net.floodlightcontroller.perfmon;
-
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * Return the performance monitoring data for the get rest api call
- * @author subrata
- */
-public class PerfMonDataResource extends ServerResource {
- protected final static Logger logger = LoggerFactory.getLogger(PerfMonDataResource.class);
-
- @Get("json")
- public CumulativeTimeBucket handleApiQuery() {
- IPktInProcessingTimeService pktinProcTime =
- (IPktInProcessingTimeService)getContext().getAttributes().
- get(IPktInProcessingTimeService.class.getCanonicalName());
-
- setStatus(Status.SUCCESS_OK, "OK");
- // Allocate output object
- if (pktinProcTime.isEnabled()) {
- CumulativeTimeBucket ctb = pktinProcTime.getCtb();
- ctb.computeAverages();
- return ctb;
- }
-
- return null;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/perfmon/PerfMonToggleResource.java b/src/main/java/net/floodlightcontroller/perfmon/PerfMonToggleResource.java
deleted file mode 100644
index 9ea1876..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/PerfMonToggleResource.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.floodlightcontroller.perfmon;
-
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-
-public class PerfMonToggleResource extends ServerResource {
-
- @Get("json")
- public String retrieve() {
- IPktInProcessingTimeService pktinProcTime =
- (IPktInProcessingTimeService)getContext().getAttributes().
- get(IPktInProcessingTimeService.class.getCanonicalName());
-
- String param = ((String)getRequestAttributes().get("perfmonstate")).toLowerCase();
- if (param.equals("reset")) {
- pktinProcTime.getCtb().reset();
- } else {
- if (param.equals("enable") || param.equals("true")) {
- pktinProcTime.setEnabled(true);
- } else if (param.equals("disable") || param.equals("false")) {
- pktinProcTime.setEnabled(false);
- }
- }
- setStatus(Status.SUCCESS_OK, "OK");
- return "{ \"enabled\" : " + pktinProcTime.isEnabled() + " }";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/perfmon/PerfWebRoutable.java b/src/main/java/net/floodlightcontroller/perfmon/PerfWebRoutable.java
deleted file mode 100644
index ace0bc8..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/PerfWebRoutable.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.floodlightcontroller.perfmon;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-public class PerfWebRoutable implements RestletRoutable {
-
- @Override
- public Restlet getRestlet(Context context) {
- Router router = new Router(context);
- router.attach("/data/json", PerfMonDataResource.class);
- router.attach("/{perfmonstate}/json", PerfMonToggleResource.class); // enable, disable, or reset
- return router;
- }
-
- @Override
- public String basePath() {
- return "/wm/performance";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/perfmon/PktInProcessingTime.java b/src/main/java/net/floodlightcontroller/perfmon/PktInProcessingTime.java
deleted file mode 100644
index 639623b..0000000
--- a/src/main/java/net/floodlightcontroller/perfmon/PktInProcessingTime.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * Performance monitoring package
- */
-package net.floodlightcontroller.perfmon;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.core.FloodlightContext;
-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.restserver.IRestApiService;
-
-import org.openflow.protocol.OFMessage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class contains a set of buckets (called time buckets as the
- * primarily contain 'times' that are used in a circular way to
- * store information on packet in processing time.
- * Each bucket is meant to store the various processing time
- * related data for a fixed duration.
- * Buckets are reused to reduce garbage generation! Once the
- * last bucket is used up the LRU bucket is reused.
- *
- * Naming convention for variable or constants
- * variable_s : value in seconds
- * variable_ms: value in milliseconds
- * variable_us: value in microseconds
- * variable_ns: value in nanoseconds
- *
- * Key Constants:
- * ONE_BUCKET_DURATION_SECONDS_INT: time duration of each bucket
- * BUCKET_SET_SIZE: Number of buckets
- * TOT_PROC_TIME_WARN_THRESHOLD_US: if processing time for a packet
- * exceeds this threshold then a warning LOG message is generated
- * TOT_PROC_TIME_ALERT_THRESHOLD_US: same as above but an alert level
- * syslog is generated instead
- *
- */
-@LogMessageCategory("Performance Monitoring")
-public class PktInProcessingTime
- implements IFloodlightModule, IPktInProcessingTimeService {
-
-
- // Our dependencies
- private IRestApiService restApi;
-
- protected long ptWarningThresholdInNano;
-
- // DB storage tables
- protected static final String ControllerTableName = "controller_controller";
- public static final String COLUMN_ID = "id";
- public static final String COLUMN_PERF_MON = "performance_monitor_feature";
-
- protected static Logger logger =
- LoggerFactory.getLogger(PktInProcessingTime.class);
-
- protected boolean isEnabled = false;
- protected boolean isInited = false;
- // Maintains the time when the last packet was processed
- protected long lastPktTime_ns;
- private CumulativeTimeBucket ctb = null;
-
-
- /***
- * BUCKET_SET_SIZE buckets each holding 10s of processing time data, a total
- * of 30*10s = 5mins of processing time data is maintained
- */
- protected static final int ONE_BUCKET_DURATION_SECONDS = 10;// seconds
- protected static final long ONE_BUCKET_DURATION_NANOSECONDS =
- ONE_BUCKET_DURATION_SECONDS * 1000000000;
-
- @Override
- public void bootstrap(List<IOFMessageListener> listeners) {
- if (!isInited) {
- ctb = new CumulativeTimeBucket(listeners);
- isInited = true;
- }
- }
-
- @Override
- public boolean isEnabled() {
- return isEnabled && isInited;
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- this.isEnabled = enabled;
- logger.debug("Setting module to " + isEnabled);
- }
-
- @Override
- public CumulativeTimeBucket getCtb() {
- return ctb;
- }
-
- private long startTimePktNs;
- private long startTimeCompNs;
- @Override
- public void recordStartTimeComp(IOFMessageListener listener) {
- if (isEnabled()) {
- startTimeCompNs = System.nanoTime();
- }
- }
-
- @Override
- public void recordEndTimeComp(IOFMessageListener listener) {
- if (isEnabled()) {
- long procTime = System.nanoTime() - startTimeCompNs;
- ctb.updateOneComponent(listener, procTime);
- }
- }
-
- @Override
- public void recordStartTimePktIn() {
- if (isEnabled()) {
- startTimePktNs = System.nanoTime();
- }
- }
-
- @Override
- @LogMessageDoc(level="WARN",
- message="Time to process packet-in exceeded threshold: {}",
- explanation="Time to process packet-in exceeded the configured " +
- "performance threshold",
- recommendation=LogMessageDoc.CHECK_CONTROLLER)
- public void recordEndTimePktIn(IOFSwitch sw, OFMessage m, FloodlightContext cntx) {
- if (isEnabled()) {
- long procTimeNs = System.nanoTime() - startTimePktNs;
- ctb.updatePerPacketCounters(procTimeNs);
-
- if (ptWarningThresholdInNano > 0 &&
- procTimeNs > ptWarningThresholdInNano) {
- logger.warn("Time to process packet-in exceeded threshold: {}",
- procTimeNs/1000);
- }
- }
- }
-
- // IFloodlightModule methods
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IPktInProcessingTimeService.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(IPktInProcessingTimeService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IRestApiService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- restApi = context.getServiceImpl(IRestApiService.class);
- }
-
- @Override
- @LogMessageDoc(level="INFO",
- message="Packet processing time threshold for warning" +
- " set to {time} ms.",
- explanation="Performance monitoring will log a warning if " +
- "packet processing time exceeds the configured threshold")
- public void startUp(FloodlightModuleContext context) {
- // Add our REST API
- restApi.addRestletRoutable(new PerfWebRoutable());
-
- // TODO - Alex - change this to a config option
- ptWarningThresholdInNano = Long.parseLong(System.getProperty(
- "net.floodlightcontroller.core.PTWarningThresholdInMilli", "0")) * 1000000;
- if (ptWarningThresholdInNano > 0) {
- logger.info("Packet processing time threshold for warning" +
- " set to {} ms.", ptWarningThresholdInNano/1000000);
- }
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
index 8a69eca..3c8d663 100644
--- a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
@@ -18,7 +18,6 @@
package net.floodlightcontroller.storage.memory;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
import net.floodlightcontroller.storage.nosql.NoSqlStorageSource;
import net.floodlightcontroller.storage.SynchronousExecutorService;
import net.floodlightcontroller.storage.IStorageSourceService;
@@ -36,7 +35,7 @@
public class MemoryStorageSource extends NoSqlStorageSource {
private Map<String, MemoryTable> tableMap = new HashMap<String,MemoryTable>();
- IPktInProcessingTimeService pktinProcessingTime;
+
synchronized private MemoryTable getTable(String tableName, boolean create) {
MemoryTable table = tableMap.get(tableName);
@@ -172,11 +171,7 @@
getTable(tableName, true);
}
- public void setPktinProcessingTime(
- IPktInProcessingTimeService pktinProcessingTime) {
- this.pktinProcessingTime = pktinProcessingTime;
- }
-
+
// IFloodlightModule methods
@Override
diff --git a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
index 775f952..6483121 100644
--- a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
+++ b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
@@ -27,7 +27,6 @@
import net.onrc.onos.ofcontroller.util.FlowPath;
import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
-import org.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -99,8 +98,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryAdded(EntryEvent event) {
- Long keyLong = (Long)event.getKey();
+ public void entryAdded(EntryEvent<Long, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -118,8 +116,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryRemoved(EntryEvent event) {
- Long keyLong = (Long)event.getKey();
+ public void entryRemoved(EntryEvent<Long, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -137,8 +134,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryUpdated(EntryEvent event) {
- Long keyLong = (Long)event.getKey();
+ public void entryUpdated(EntryEvent<Long, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -156,7 +152,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryEvicted(EntryEvent event) {
+ public void entryEvicted(EntryEvent<Long, byte[]> event) {
// NOTE: We don't use eviction for this map
}
}
@@ -174,14 +170,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryAdded(EntryEvent event) {
- //
- // NOTE: Ignore Flow Entries Events originated by this instance
- //
- if (event.getMember().localMember())
- return;
-
- Long keyLong = (Long)event.getKey();
+ public void entryAdded(EntryEvent<Long, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -199,14 +188,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryRemoved(EntryEvent event) {
- //
- // NOTE: Ignore Flow Entries Events originated by this instance
- //
- if (event.getMember().localMember())
- return;
-
- Long keyLong = (Long)event.getKey();
+ public void entryRemoved(EntryEvent<Long, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -224,14 +206,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryUpdated(EntryEvent event) {
- //
- // NOTE: Ignore Flow Entries Events originated by this instance
- //
- if (event.getMember().localMember())
- return;
-
- Long keyLong = (Long)event.getKey();
+ public void entryUpdated(EntryEvent<Long, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -249,7 +224,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryEvicted(EntryEvent event) {
+ public void entryEvicted(EntryEvent<Long, byte[]> event) {
// NOTE: We don't use eviction for this map
}
}
@@ -267,8 +242,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryAdded(EntryEvent event) {
- String keyString = (String)event.getKey();
+ public void entryAdded(EntryEvent<String, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -287,8 +261,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryRemoved(EntryEvent event) {
- String keyString = (String)event.getKey();
+ public void entryRemoved(EntryEvent<String, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -307,8 +280,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryUpdated(EntryEvent event) {
- String keyString = (String)event.getKey();
+ public void entryUpdated(EntryEvent<String, byte[]> event) {
byte[] valueBytes = (byte[])event.getValue();
//
@@ -327,7 +299,7 @@
*
* @param event the notification event for the entry.
*/
- public void entryEvicted(EntryEvent event) {
+ public void entryEvicted(EntryEvent<String, byte[]> event) {
// NOTE: We don't use eviction for this map
}
}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
index bfd9046..03b4c96 100644
--- a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
+++ b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
@@ -176,9 +176,14 @@
*/
public IPortObject searchPort(String dpid, Short number) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ if ( fg == null ) return null;
String id = dpid + number.toString();
- return (fg != null && fg.getVertices("port_id",id).iterator().hasNext()) ?
- fg.getVertices("port_id",id,IPortObject.class).iterator().next() : null;
+ Iterator<IPortObject> ports = fg.getVertices("port_id",id,IPortObject.class).iterator();
+ if ( ports.hasNext() ) {
+ return ports.next();
+ } else {
+ return null;
+ }
}
/**
@@ -206,10 +211,14 @@
* @param macAddr MAC address to search and get
*/
public IDeviceObject searchDevice(String macAddr) {
- // TODO Auto-generated method stub
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- return (fg != null && fg.getVertices("dl_addr",macAddr).iterator().hasNext()) ?
- fg.getVertices("dl_addr",macAddr, IDeviceObject.class).iterator().next() : null;
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ if ( fg == null ) return null;
+ Iterator<IDeviceObject> devices = fg.getVertices("dl_addr",macAddr, IDeviceObject.class).iterator();
+ if ( devices.hasNext() ) {
+ return devices.next();
+ } else {
+ return null;
+ }
}
/**
@@ -288,10 +297,13 @@
*/
public IFlowPath searchFlowPath(FlowId flowId) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
- return fg.getVertices("flow_id", flowId.toString()).iterator().hasNext() ?
- fg.getVertices("flow_id", flowId.toString(),
- IFlowPath.class).iterator().next() : null;
+ if ( fg == null ) return null;
+ Iterator<IFlowPath> flowpaths = fg.getVertices("flow_id", flowId.toString(), IFlowPath.class).iterator();
+ if ( flowpaths.hasNext() ) {
+ return flowpaths.next();
+ } else {
+ return null;
+ }
}
/**
@@ -299,10 +311,10 @@
* @param flowEntry flow entry object
*/
public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
- GremlinPipeline<Vertex, IFlowPath> pipe = new GremlinPipeline<Vertex, IFlowPath>();
- pipe.start(flowEntry.asVertex());
- pipe.out("flow");
- FramedVertexIterable<IFlowPath> r = new FramedVertexIterable(conn.getFramedGraph(), (Iterable) pipe, IFlowPath.class);
+ GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
+ pipe.start(flowEntry.asVertex()).out("flow");
+ FramedVertexIterable<IFlowPath> r = new FramedVertexIterable<IFlowPath>(conn.getFramedGraph(),
+ (Iterable<Vertex>) pipe, IFlowPath.class);
return r.iterator().hasNext() ? r.iterator().next() : null;
}
@@ -348,10 +360,13 @@
*/
public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
- return fg.getVertices("flow_entry_id", flowEntryId.toString()).iterator().hasNext() ?
- fg.getVertices("flow_entry_id", flowEntryId.toString(),
- IFlowEntry.class).iterator().next() : null;
+ if ( fg == null ) return null;
+ Iterator<IFlowEntry> flowentries = fg.getVertices("flow_entry_id", flowEntryId.toString(), IFlowEntry.class).iterator();
+ if ( flowentries.hasNext() ) {
+ return flowentries.next();
+ } else {
+ return null;
+ }
}
/**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java
index 5db8f0a..cc454ec 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java
@@ -14,7 +14,6 @@
public class Interface {
private final String name;
- private final SwitchPort switchPort;
private final long dpid;
private final short port;
private final InetAddress ipAddress;
@@ -31,7 +30,6 @@
this.port = port;
this.ipAddress = InetAddresses.forString(ipAddress);
this.prefixLength = prefixLength;
- this.switchPort = new SwitchPort(new Dpid(this.dpid), new Port(this.port));
}
public String getName() {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Ptree.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Ptree.java
index 041061c..c80d055 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Ptree.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Ptree.java
@@ -244,7 +244,6 @@
add.parent = node;
}
- @SuppressWarnings("unused")
private PtreeNode node_common(PtreeNode node, byte [] key, int key_bits) {
int i;
int limit = Math.min(node.keyBits, key_bits) / 8;
@@ -275,8 +274,6 @@
}
PtreeNode add = new PtreeNode(null, common_len, maxKeyOctets);
- if (add == null)
- return null;
int j;
for (j = 0; j < i; j++)
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
index 49ffd4e..29c4377 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -1,7 +1,5 @@
package net.onrc.onos.ofcontroller.core;
-import net.onrc.onos.ofcontroller.flowmanager.web.DatapathSummarySerializer;
-
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -13,6 +11,9 @@
import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
import com.tinkerpop.frames.VertexFrame;
+import net.onrc.onos.ofcontroller.flowmanager.web.DatapathSummarySerializer;
+import net.floodlightcontroller.core.web.serializers.IPv4Serializer;
+
/*
* This is the interfaces to make the objects for Cassandra DB.
* They are interfaces, but it is also implementation,
@@ -205,6 +206,7 @@
@JsonProperty("ipv4")
@Property("ipv4_address")
+ @JsonSerialize(using=IPv4Serializer.class)
public int getIpv4Address();
@Property("ipv4_address")
@@ -251,6 +253,20 @@
@Property("flow_path_flags")
public void setFlowPathFlags(Long flowPathFlags);
+ @JsonProperty("idleTimeout")
+ @Property("idle_timeout")
+ public Integer getIdleTimeout();
+
+ @Property("idle_timeout")
+ public void setIdleTimeout(Integer idleTimeout);
+
+ @JsonProperty("hardTimeout")
+ @Property("hard_timeout")
+ public Integer getHardTimeout();
+
+ @Property("hard_timeout")
+ public void setHardTimeout(Integer hardTimeout);
+
@JsonProperty("srcDpid")
@Property("src_switch")
public String getSrcSwitch();
@@ -405,6 +421,20 @@
@Property("flow_entry_id")
public void setFlowEntryId(String flowEntryId);
+ @JsonProperty("idleTimeout")
+ @Property("idle_timeout")
+ public Integer getIdleTimeout();
+
+ @Property("idle_timeout")
+ public void setIdleTimeout(Integer idleTimeout);
+
+ @JsonProperty("hardTimeout")
+ @Property("hard_timeout")
+ public Integer getHardTimeout();
+
+ @Property("hard_timeout")
+ public void setHardTimeout(Integer hardTimeout);
+
@Property("switch_dpid")
public String getSwitchDpid();
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 f5f8b00..4bbc054 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
@@ -80,6 +80,10 @@
log.debug("Adding device {}: creating new device", device.getMACAddressString());
}
+ if (obj == null) {
+ return null;
+ }
+
changeDeviceAttachments(device, obj);
changeDeviceIpv4Addresses(device, obj);
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
index 7a3d43e..635e24e 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
@@ -14,10 +14,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.pipes.PipeFunction;
-import com.tinkerpop.pipes.transform.PathPipe;
-
/**
* This is the class for storing the information of links into GraphDB
*/
@@ -490,33 +486,4 @@
return success;
}
-
- // TODO should be moved to TopoLinkServiceImpl (never used in this class)
- static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
-
- @SuppressWarnings("unchecked")
- @Override
- public Link compute(PathPipe<Vertex> pipe ) {
- long s_dpid = 0;
- long d_dpid = 0;
- short s_port = 0;
- short d_port = 0;
- List<Vertex> V = new ArrayList<Vertex>();
- V = (List<Vertex>)pipe.next();
- Vertex src_sw = V.get(0);
- Vertex dest_sw = V.get(3);
- Vertex src_port = V.get(1);
- Vertex dest_port = V.get(2);
- s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
- d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
- s_port = (Short) src_port.getProperty("number");
- d_port = (Short) dest_port.getProperty("number");
-
- Link l = new Link(s_dpid,s_port,d_dpid,d_port);
-
- return l;
- }
- }
-
-
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
index dcfdc73..5f51b58 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
@@ -348,7 +348,6 @@
IPortObject p = sw.getPort(port);
if (p != null) {
log.info("SwitchStorage:deletePort dpid:{} port:{} found and set INACTIVE", dpid, port);
- //deletePortImpl(p);
p.setState("INACTIVE");
// XXX for now delete devices when we change a port to prevent
@@ -492,12 +491,4 @@
new Object[] {port.getPortId(), state, desc});
}
}
-
- private void deletePortImpl(IPortObject port) {
- if (port != null) {
- op.removePort(port);
- log.info("SwitchStorage:deletePortImpl port:{} done",
- port.getPortId());
- }
- }
}
\ No newline at end of file
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 b692e8e..f1f015a 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
@@ -7,13 +7,15 @@
import net.onrc.onos.graph.GraphDBOperation;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
-import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl.ExtractLink;
+import org.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.gremlin.java.GremlinPipeline;
+import com.tinkerpop.pipes.PipeFunction;
+import com.tinkerpop.pipes.transform.PathPipe;
public class TopoLinkServiceImpl implements ITopoLinkService {
@@ -31,7 +33,6 @@
@Override
public List<Link> getActiveLinks() {
- // TODO Auto-generated method stub
op = new GraphDBOperation("");
op.commit(); //Commit to ensure we see latest data
Iterable<ISwitchObject> switches = op.getActiveSwitches();
@@ -56,7 +57,6 @@
@Override
public List<Link> getLinksOnSwitch(String dpid) {
- // TODO Auto-generated method stub
List<Link> links = new ArrayList<Link>();
ISwitchObject sw = op.searchSwitch(dpid);
GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
@@ -73,5 +73,29 @@
return links;
}
-
+
+ private class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
+ @Override
+ public Link compute(PathPipe<Vertex> pipe) {
+ long s_dpid = 0;
+ long d_dpid = 0;
+ short s_port = 0;
+ short d_port = 0;
+
+ @SuppressWarnings("unchecked")
+ List<Vertex> V = pipe.next();
+ Vertex src_sw = V.get(0);
+ Vertex dest_sw = V.get(3);
+ Vertex src_port = V.get(1);
+ Vertex dest_port = V.get(2);
+ s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
+ d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
+ s_port = (Short) src_port.getProperty("number");
+ d_port = (Short) dest_port.getProperty("number");
+
+ Link l = new Link(s_dpid,s_port,d_dpid,d_port);
+
+ return l;
+ }
+ }
}
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 50fe8f8..4b31667 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -39,7 +39,6 @@
import net.onrc.onos.ofcontroller.core.ISwitchStorage;
import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
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 1babafa..da407ab 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -3,10 +3,8 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
-import java.util.concurrent.ConcurrentLinkedQueue;
import net.floodlightcontroller.util.MACAddress;
@@ -90,6 +88,8 @@
// - flowPath.flowPathType()
// - flowPath.flowPathUserState()
// - flowPath.flowPathFlags()
+ // - flowPath.idleTimeout()
+ // - flowPath.hardTimeout()
// - flowPath.dataPath().srcPort()
// - flowPath.dataPath().dstPort()
// - flowPath.matchSrcMac()
@@ -109,6 +109,8 @@
flowObj.setFlowPathType(flowPath.flowPathType().toString());
flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
+ flowObj.setIdleTimeout(flowPath.idleTimeout());
+ flowObj.setHardTimeout(flowPath.hardTimeout());
flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
@@ -225,6 +227,8 @@
// - InPort edge
// - OutPort edge
//
+ // - flowEntry.idleTimeout()
+ // - flowEntry.hardTimeout()
// - flowEntry.dpid()
// - flowEntry.flowEntryUserState()
// - flowEntry.flowEntrySwitchState()
@@ -245,6 +249,8 @@
// - flowEntry.actions()
//
ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
+ flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
+ flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
flowEntryObj.setSwitch(sw);
if (flowEntry.flowEntryMatch().matchInPort()) {
@@ -509,6 +515,8 @@
String flowPathType = flowObj.getFlowPathType();
String flowPathUserState = flowObj.getFlowPathUserState();
Long flowPathFlags = flowObj.getFlowPathFlags();
+ Integer idleTimeout = flowObj.getIdleTimeout();
+ Integer hardTimeout = flowObj.getHardTimeout();
String srcSwitchStr = flowObj.getSrcSwitch();
Short srcPortShort = flowObj.getSrcPort();
String dstSwitchStr = flowObj.getDstSwitch();
@@ -519,6 +527,8 @@
(flowPathType == null) ||
(flowPathUserState == null) ||
(flowPathFlags == null) ||
+ (idleTimeout == null) ||
+ (hardTimeout == null) ||
(srcSwitchStr == null) ||
(srcPortShort == null) ||
(dstSwitchStr == null) ||
@@ -533,6 +543,8 @@
flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
+ flowPath.setIdleTimeout(idleTimeout);
+ flowPath.setHardTimeout(hardTimeout);
flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
@@ -611,11 +623,15 @@
*/
public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
String flowEntryIdStr = flowEntryObj.getFlowEntryId();
+ Integer idleTimeout = flowEntryObj.getIdleTimeout();
+ Integer hardTimeout = flowEntryObj.getHardTimeout();
String switchDpidStr = flowEntryObj.getSwitchDpid();
String userState = flowEntryObj.getUserState();
String switchState = flowEntryObj.getSwitchState();
if ((flowEntryIdStr == null) ||
+ (idleTimeout == null) ||
+ (hardTimeout == null) ||
(switchDpidStr == null) ||
(userState == null) ||
(switchState == null)) {
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 6c200fa..3538eb4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -75,11 +75,14 @@
// Transient state for processing the Flow Paths:
// - The Flow Paths that should be recomputed
// - The Flow Paths with modified Flow Entries
+ // - The Flow Paths that we should check if installed in all switches
//
private Map<Long, FlowPath> shouldRecomputeFlowPaths =
new HashMap<Long, FlowPath>();
private Map<Long, FlowPath> modifiedFlowPaths =
new HashMap<Long, FlowPath>();
+ private Map<Long, FlowPath> checkIfInstalledFlowPaths =
+ new HashMap<Long, FlowPath>();
/**
* Constructor for a given Flow Manager and Datagrid Service.
@@ -239,6 +242,12 @@
for (FlowPath flowPath : modifiedFlowPaths.values())
flowPath.dataPath().removeDeletedFlowEntries();
+ //
+ // Check if Flow Paths have been installed into all switches,
+ // and generate the appropriate events.
+ //
+ checkInstalledFlowPaths(checkIfInstalledFlowPaths.values());
+
// Cleanup
topologyEvents.clear();
flowPathEvents.clear();
@@ -246,6 +255,44 @@
//
shouldRecomputeFlowPaths.clear();
modifiedFlowPaths.clear();
+ checkIfInstalledFlowPaths.clear();
+ }
+
+ /**
+ * Check if Flow Paths have been installed into all switches,
+ * and generate the appropriate events.
+ *
+ * @param flowPaths the flowPaths to process.
+ */
+ private void checkInstalledFlowPaths(Collection<FlowPath> flowPaths) {
+ List<FlowPath> installedFlowPaths = new LinkedList<FlowPath>();
+
+ Kryo kryo = kryoFactory.newKryo();
+
+ for (FlowPath flowPath : flowPaths) {
+ boolean isInstalled = true;
+
+ //
+ // Check whether all Flow Entries have been installed
+ //
+ for (FlowEntry flowEntry : flowPath.flowEntries()) {
+ if (flowEntry.flowEntrySwitchState() !=
+ FlowEntrySwitchState.FE_SWITCH_UPDATED) {
+ isInstalled = false;
+ break;
+ }
+ }
+
+ if (isInstalled) {
+ // Create a copy and add it to the list
+ FlowPath copyFlowPath = kryo.copy(flowPath);
+ installedFlowPaths.add(copyFlowPath);
+ }
+ }
+ kryoFactory.deleteKryo(kryo);
+
+ // Generate an event for the installed Flow Path.
+ flowManager.notificationFlowPathsInstalled(installedFlowPaths);
}
/**
@@ -340,6 +387,9 @@
}
modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
break;
+ case FP_TYPE_UNKNOWN:
+ log.error("FlowPath event with unknown type");
+ break;
}
allFlowPaths.put(flowPath.flowId().value(), flowPath);
@@ -526,10 +576,12 @@
}
//
- // Update the local Flow Entry.
+ // Update the local Flow Entry, and keep state to check
+ // if the Flow Path has been installed.
//
localFlowEntry.setFlowEntryUserState(flowEntry.flowEntryUserState());
localFlowEntry.setFlowEntrySwitchState(flowEntry.flowEntrySwitchState());
+ checkIfInstalledFlowPaths.put(flowPath.flowId().value(), flowPath);
return localFlowEntry;
}
@@ -700,6 +752,12 @@
newFlowEntry.setFlowId(new FlowId(flowPath.flowId().value()));
//
+ // Copy the Flow timeouts
+ //
+ newFlowEntry.setIdleTimeout(flowPath.idleTimeout());
+ newFlowEntry.setHardTimeout(flowPath.hardTimeout());
+
+ //
// Allocate the FlowEntryMatch by copying the default one
// from the FlowPath (if set).
//
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 7ef49ef..41cf670 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -10,8 +10,6 @@
import java.util.SortedMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
@@ -23,15 +21,13 @@
import net.onrc.onos.datagrid.IDatagridService;
import net.onrc.onos.graph.GraphDBOperation;
import net.onrc.onos.ofcontroller.core.INetMapStorage;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
+import net.onrc.onos.ofcontroller.forwarding.IForwardingService;
import net.onrc.onos.ofcontroller.topology.Topology;
import net.onrc.onos.ofcontroller.util.*;
-import org.openflow.protocol.OFType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,6 +45,7 @@
protected FlowEventHandler flowEventHandler;
protected IFlowPusherService pusher;
+ protected IForwardingService forwardingService;
// Flow Entry ID generation state
private static Random randomGenerator = new Random();
@@ -134,7 +131,8 @@
l.add(INetworkGraphService.class);
l.add(IDatagridService.class);
l.add(IRestApiService.class);
- l.add(IFlowPusherService.class);
+ l.add(IFlowPusherService.class);
+ l.add(IForwardingService.class);
return l;
}
@@ -151,6 +149,7 @@
datagridService = context.getServiceImpl(IDatagridService.class);
restApi = context.getServiceImpl(IRestApiService.class);
pusher = context.getServiceImpl(IFlowPusherService.class);
+ forwardingService = context.getServiceImpl(IForwardingService.class);
this.init("");
}
@@ -352,8 +351,25 @@
* @param sw the switch the Flow Entry expired on.
* @param flowEntryId the Flow Entry ID of the expired Flow Entry.
*/
- public void flowEntryOnSwitchExpired(IOFSwitch sw, FlowEntryId flowEntryId) {
- // TODO: Not implemented yet
+ public void flowEntryOnSwitchExpired(IOFSwitch sw,
+ FlowEntryId flowEntryId) {
+ // Find the Flow Entry
+ FlowEntry flowEntry = datagridService.getFlowEntry(flowEntryId);
+ if (flowEntryId == null)
+ return; // Flow Entry not found
+
+ // Find the Flow Path
+ FlowPath flowPath = datagridService.getFlow(flowEntry.flowId());
+ if (flowPath == null)
+ return; // Flow Path not found
+
+ //
+ // Remove the Flow if the Flow Entry expired on the first switch
+ //
+ Dpid srcDpid = flowPath.dataPath().srcPort().dpid();
+ if (srcDpid.value() != sw.getId())
+ return;
+ deleteFlow(flowPath.flowId());
}
/**
@@ -370,7 +386,6 @@
// Process all entries
//
for (Pair<IOFSwitch, FlowEntry> entry : entries) {
- IOFSwitch sw = entry.first;
FlowEntry flowEntry = entry.second;
//
@@ -391,11 +406,24 @@
case FE_USER_DELETE:
datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
break;
+ case FE_USER_UNKNOWN:
+ assert(false);
+ break;
}
}
}
/**
+ * Generate a notification that a collection of Flow Paths has been
+ * installed in the network.
+ *
+ * @param flowPaths the collection of installed Flow Paths.
+ */
+ void notificationFlowPathsInstalled(Collection<FlowPath> flowPaths) {
+ forwardingService.flowsInstalled(flowPaths);
+ }
+
+ /**
* 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/flowmanager/IFlowService.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
index a25602d..549a0fc 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
@@ -6,8 +6,6 @@
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.onrc.onos.ofcontroller.topology.Topology;
-import net.onrc.onos.ofcontroller.util.CallerId;
-import net.onrc.onos.ofcontroller.util.DataPathEndpoints;
import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryId;
import net.onrc.onos.ofcontroller.util.FlowId;
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 461d231..a4f0a8c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
@@ -42,9 +42,8 @@
public class FlowProgrammer implements IFloodlightModule,
IOFMessageListener,
IOFSwitchListener {
- @SuppressWarnings("unused")
// flag to enable FlowSynchronizer
- private static final boolean enableFlowSync = false;
+ private static final boolean enableFlowSync = true;
protected static Logger log = LoggerFactory.getLogger(FlowProgrammer.class);
protected volatile IFloodlightProviderService floodlightProvider;
protected volatile IControllerRegistryService registryService;
@@ -155,8 +154,10 @@
public void addedSwitch(IOFSwitch sw) {
log.debug("Switch added: {}", sw.getId());
- if (enableFlowSync && registryService.hasControl(sw.getId())) {
- synchronizer.synchronize(sw);
+ if (enableFlowSync) {
+ if (registryService.hasControl(sw.getId())) {
+ synchronizer.synchronize(sw);
+ }
}
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
index c3c7107..3f61248 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
@@ -34,7 +34,6 @@
import net.onrc.onos.ofcontroller.util.FlowEntryAction.*;
import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryActions;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
import net.onrc.onos.ofcontroller.util.FlowEntryUserState;
import net.onrc.onos.ofcontroller.util.IPv4Net;
@@ -68,8 +67,6 @@
protected static final int MAX_MESSAGE_SEND = 100;
public static final short PRIORITY_DEFAULT = 100;
- public static final short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 0; // infinity
- public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0; // infinite
public enum QueueState {
READY,
@@ -82,8 +79,9 @@
* @author Naoki Shiota
*
*/
- @SuppressWarnings("serial")
private class SwitchQueue extends ArrayDeque<OFMessage> {
+ private static final long serialVersionUID = 1L;
+
QueueState state;
// Max rate of sending message (bytes/ms). 0 implies no limitation.
@@ -722,8 +720,8 @@
}
}
- fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
- .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
+ fm.setIdleTimeout((short)flowEntry.idleTimeout())
+ .setHardTimeout((short)flowEntry.hardTimeout())
.setPriority(PRIORITY_DEFAULT)
.setBufferId(OFPacketOut.BUFFER_ID_NONE).setCookie(cookie)
.setCommand(flowModCommand).setMatch(match)
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 7d5527b..6ef44be 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
@@ -7,8 +7,10 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import org.openflow.protocol.OFFlowMod;
import org.openflow.protocol.OFMatch;
@@ -44,26 +46,27 @@
private GraphDBOperation dbHandler;
protected IFlowPusherService pusher;
- private Map<IOFSwitch, Thread> switchThreads;
+ private Map<IOFSwitch, FutureTask<SyncResult>> switchThreads;
public FlowSynchronizer() {
dbHandler = new GraphDBOperation("");
- switchThreads = new HashMap<IOFSwitch, Thread>();
+ switchThreads = new HashMap<IOFSwitch, FutureTask<SyncResult>>();
}
@Override
- public void synchronize(IOFSwitch sw) {
+ public Future<SyncResult> synchronize(IOFSwitch sw) {
Synchronizer sync = new Synchronizer(sw);
- Thread t = new Thread(sync);
- switchThreads.put(sw, t);
- t.start();
+ FutureTask<SyncResult> task = new FutureTask<SyncResult>(sync);
+ switchThreads.put(sw, task);
+ task.run();
+ return task;
}
@Override
public void interrupt(IOFSwitch sw) {
- Thread t = switchThreads.remove(sw);
+ FutureTask<SyncResult> t = switchThreads.remove(sw);
if(t != null) {
- t.interrupt();
+ t.cancel(true);
}
}
@@ -80,7 +83,7 @@
* @author Brian
*
*/
- protected class Synchronizer implements Runnable {
+ protected class Synchronizer implements Callable<SyncResult> {
IOFSwitch sw;
ISwitchObject swObj;
@@ -90,14 +93,45 @@
this.swObj = dbHandler.searchSwitch(dpid.toString());
}
+ double graphIDTime, switchTime, compareTime, graphEntryTime, extractTime, pushTime, totalTime;
@Override
- public void run() {
+ public SyncResult call() {
// TODO: stop adding other flow entries while synchronizing
//pusher.suspend(sw);
+ long start = System.nanoTime();
Set<FlowEntryWrapper> graphEntries = getFlowEntriesFromGraph();
+ long step1 = System.nanoTime();
Set<FlowEntryWrapper> switchEntries = getFlowEntriesFromSwitch();
- compare(graphEntries, switchEntries);
+ long step2 = System.nanoTime();
+ SyncResult result = compare(graphEntries, switchEntries);
+ long step3 = System.nanoTime();
+ graphIDTime = (step1 - start);
+ switchTime = (step2 - step1);
+ compareTime = (step3 - step2);
+ totalTime = (step3 - start);
+ outputTime();
//pusher.resume(sw);
+
+ return result;
+ }
+
+ private void outputTime() {
+ double div = Math.pow(10, 6); //convert nanoseconds to ms
+ graphIDTime /= div;
+ switchTime /= div;
+ compareTime = (compareTime - graphEntryTime - extractTime - pushTime) / div;
+ graphEntryTime /= div;
+ extractTime /= div;
+ pushTime /= div;
+ totalTime /= div;
+ log.debug("Sync time (ms):" +
+ graphIDTime + "," +
+ switchTime + "," +
+ compareTime + "," +
+ graphEntryTime + "," +
+ extractTime + "," +
+ pushTime + "," +
+ totalTime);
}
/**
@@ -107,7 +141,7 @@
* @param graphEntries Flow entries in GraphDB.
* @param switchEntries Flow entries in switch.
*/
- private void compare(Set<FlowEntryWrapper> graphEntries, Set<FlowEntryWrapper> switchEntries) {
+ private SyncResult compare(Set<FlowEntryWrapper> graphEntries, Set<FlowEntryWrapper> switchEntries) {
int added = 0, removed = 0, skipped = 0;
for(FlowEntryWrapper entry : switchEntries) {
if(graphEntries.contains(entry)) {
@@ -123,11 +157,16 @@
for(FlowEntryWrapper entry : graphEntries) {
// add flow entry to switch
entry.addToSwitch(sw);
+ graphEntryTime += entry.dbTime;
+ extractTime += entry.extractTime;
+ pushTime += entry.pushTime;
added++;
}
log.debug("Flow entries added "+ added + ", " +
"Flow entries removed "+ removed + ", " +
"Flow entries skipped " + skipped);
+
+ return new SyncResult(added, removed, skipped);
}
/**
@@ -216,6 +255,7 @@
* Install this FlowEntry to a switch via FlowPusher.
* @param sw Switch to which flow will be installed.
*/
+ double dbTime, extractTime, pushTime;
public void addToSwitch(IOFSwitch sw) {
if (statisticsReply != null) {
log.error("Error adding existing flow entry {} to sw {}",
@@ -223,6 +263,7 @@
return;
}
+ double startDB = System.nanoTime();
// Get the Flow Entry state from the Network Graph
IFlowEntry iFlowEntry = null;
try {
@@ -237,7 +278,9 @@
flowEntryId, sw.getId());
return;
}
+ dbTime = System.nanoTime() - startDB;
+ double startExtract = System.nanoTime();
FlowEntry flowEntry =
FlowDatabaseOperation.extractFlowEntry(iFlowEntry);
if (flowEntry == null) {
@@ -245,8 +288,11 @@
flowEntryId, sw.getId());
return;
}
-
+ extractTime = System.nanoTime() - startExtract;
+
+ double startPush = System.nanoTime();
pusher.pushFlowEntry(sw, flowEntry);
+ pushTime = System.nanoTime() - startPush;
}
/**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowSyncService.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowSyncService.java
index 4e6efaf..4fe0857 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowSyncService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowSyncService.java
@@ -1,7 +1,8 @@
package net.onrc.onos.ofcontroller.flowprogrammer;
+import java.util.concurrent.Future;
+
import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.IOFSwitchListener;
import net.floodlightcontroller.core.module.IFloodlightService;
/**
@@ -11,7 +12,19 @@
*
*/
public interface IFlowSyncService extends IFloodlightService {
- public void synchronize(IOFSwitch sw);
+ public Future<SyncResult> synchronize(IOFSwitch sw);
public void interrupt(IOFSwitch sw);
+
+ public class SyncResult {
+ public final int flowAdded;
+ public final int flowRemoved;
+ public final int flowSkipped;
+
+ public SyncResult(int added, int removed, int skipped) {
+ flowAdded = added;
+ flowRemoved = removed;
+ flowSkipped = skipped;
+ }
+ }
}
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 f33f986..3725d5e 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -3,9 +3,11 @@
import java.io.IOException;
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.concurrent.ConcurrentHashMap;
import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -46,28 +48,80 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class Forwarding implements IOFMessageListener, IFloodlightModule {
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+
+public class Forwarding implements IOFMessageListener, IFloodlightModule,
+ IForwardingService {
private final static Logger log = LoggerFactory.getLogger(Forwarding.class);
private IFloodlightProviderService floodlightProvider;
private IFlowService flowService;
+ @SuppressWarnings("unused")
private IDatagridService datagridService;
private IDeviceStorage deviceStorage;
private TopologyManager topologyService;
- public Forwarding() {
+ private Map<Path, Long> pendingFlows;
+ private Multimap<Long, PacketToPush> waitingPackets;
+
+ public class PacketToPush {
+ public final OFPacketOut packet;
+ public final long dpid;
+ public PacketToPush(OFPacketOut packet, long dpid) {
+ this.packet = packet;
+ this.dpid = dpid;
+ }
+ }
+
+ public final class Path {
+ public final SwitchPort srcPort;
+ public final SwitchPort dstPort;
+
+ public Path(SwitchPort src, SwitchPort dst) {
+ 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()));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Path)) {
+ return false;
+ }
+
+ Path otherPath = (Path) other;
+ return srcPort.equals(otherPath.srcPort) &&
+ dstPort.equals(otherPath.dstPort);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 17;
+ hash = 31 * hash + srcPort.hashCode();
+ hash = 31 * hash + dstPort.hashCode();
+ return hash;
+ }
}
@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- return null;
+ List<Class<? extends IFloodlightService>> services =
+ new ArrayList<Class<? extends IFloodlightService>>(1);
+ services.add(IForwardingService.class);
+ return services;
}
@Override
public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
- return null;
+ Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
+ new HashMap<Class<? extends IFloodlightService>, IFloodlightService>(1);
+ impls.put(IForwardingService.class, this);
+ return impls;
}
@Override
@@ -89,6 +143,10 @@
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+ pendingFlows = new ConcurrentHashMap<Path, Long>();
+ waitingPackets = Multimaps.synchronizedSetMultimap(
+ HashMultimap.<Long, PacketToPush>create());
+
deviceStorage = new DeviceStorageImpl();
deviceStorage.init("");
topologyService = new TopologyManager();
@@ -141,7 +199,8 @@
}
private void handlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
- String destinationMac = HexString.toHexString(eth.getDestinationMACAddress());
+ String destinationMac =
+ HexString.toHexString(eth.getDestinationMACAddress());
IDeviceObject deviceObject = deviceStorage.getDeviceByMac(
destinationMac);
@@ -151,7 +210,7 @@
return;
}
- Iterator<IPortObject> ports = deviceObject.getAttachedPorts().iterator();
+ Iterator<IPortObject> ports = deviceObject.getAttachedPorts().iterator();
if (!ports.hasNext()) {
log.debug("No attachment point found for device {}", destinationMac);
return;
@@ -171,46 +230,32 @@
MACAddress srcMacAddress = MACAddress.valueOf(eth.getSourceMACAddress());
MACAddress dstMacAddress = MACAddress.valueOf(eth.getDestinationMACAddress());
- if (flowExists(srcSwitchPort, srcMacAddress,
- dstSwitchPort, dstMacAddress)) {
- log.debug("Not adding flow because it already exists");
+
+ DataPath datapath = new DataPath();
+ datapath.setSrcPort(srcSwitchPort);
+ datapath.setDstPort(dstSwitchPort);
+
+
+
+ Path pathspec = new Path(srcSwitchPort, dstSwitchPort);
+ // TODO check concurrency
+ Long existingFlowId = pendingFlows.get(pathspec);
+
+ if (existingFlowId != null) {
+ log.debug("Found existing flow {}",
+ HexString.toHexString(existingFlowId));
- // TODO check reverse flow as well
-
- DataPath shortestPath =
- topologyService.getDatabaseShortestPath(srcSwitchPort, dstSwitchPort);
-
- if (shortestPath == null || shortestPath.flowEntries().isEmpty()) {
- log.warn("No path found between {} and {} - not handling packet",
- srcSwitchPort, dstSwitchPort);
- return;
- }
-
- Port outPort = shortestPath.flowEntries().get(0).outPort();
- forwardPacket(pi, sw, outPort.value());
+ // TODO do stuff.
+ OFPacketOut po = constructPacketOut(datapath, pi, sw);
+ waitingPackets.put(existingFlowId, new PacketToPush(po, sw.getId()));
return;
}
- // Calculate a shortest path before pushing flow mods.
- // This will be used later by the packet-out processing, but it uses
- // the database so will be slow, and we should do it before flow mods.
- DataPath shortestPath =
- topologyService.getDatabaseShortestPath(srcSwitchPort, dstSwitchPort);
-
- if (shortestPath == null || shortestPath.flowEntries().isEmpty()) {
- log.warn("No path found between {} and {} - not handling packet",
- srcSwitchPort, dstSwitchPort);
- return;
- }
log.debug("Adding new flow between {} at {} and {} at {}",
new Object[]{srcMacAddress, srcSwitchPort, dstMacAddress, dstSwitchPort});
- DataPath dataPath = new DataPath();
- dataPath.setSrcPort(srcSwitchPort);
- dataPath.setDstPort(dstSwitchPort);
-
CallerId callerId = new CallerId("Forwarding");
//FlowId flowId = new FlowId(flowService.getNextFlowEntryId());
@@ -226,18 +271,13 @@
// For now just forward IPv4 packets. This prevents accidentally
// forwarding other stuff like ARP.
flowPath.flowEntryMatch().enableEthernetFrameType(Ethernet.TYPE_IPv4);
- flowPath.setDataPath(dataPath);
+ flowPath.setDataPath(datapath);
- FlowId flowId = flowService.addFlow(flowPath);
- //flowService.addFlow(flowPath, flowId);
-
-
DataPath reverseDataPath = new DataPath();
// Reverse the ports for the reverse path
reverseDataPath.setSrcPort(dstSwitchPort);
reverseDataPath.setDstPort(srcSwitchPort);
- //FlowId reverseFlowId = new FlowId(flowService.getNextFlowEntryId());
// TODO implement copy constructor for FlowPath
FlowPath reverseFlowPath = new FlowPath();
//reverseFlowPath.setFlowId(reverseFlowId);
@@ -253,13 +293,25 @@
reverseFlowPath.dataPath().srcPort().dpid().toString();
// TODO what happens if no path exists?
- //flowService.addFlow(reverseFlowPath, reverseFlowId);
- FlowId reverseFlowId = flowService.addFlow(reverseFlowPath);
+ FlowId flowId = new FlowId(flowService.getNextFlowEntryId());
+ FlowId reverseFlowId = new FlowId(flowService.getNextFlowEntryId());
- Port outPort = shortestPath.flowEntries().get(0).outPort();
- forwardPacket(pi, sw, outPort.value());
+ flowPath.setFlowId(flowId);
+ reverseFlowPath.setFlowId(reverseFlowId);
+
+ OFPacketOut po = constructPacketOut(datapath, pi, sw);
+ Path reversePathSpec = new Path(dstSwitchPort, srcSwitchPort);
+
+ // Add to waiting lists
+ pendingFlows.put(pathspec, flowId.value());
+ pendingFlows.put(reversePathSpec, reverseFlowId.value());
+ waitingPackets.put(flowId.value(), new PacketToPush(po, sw.getId()));
+
+ flowService.addFlow(reverseFlowPath);
+ flowService.addFlow(flowPath);
}
+ /*
private boolean flowExists(SwitchPort srcPort, MACAddress srcMac,
SwitchPort dstPort, MACAddress dstMac) {
for (FlowPath flow : datagridService.getAllFlows()) {
@@ -285,17 +337,18 @@
return false;
}
+ */
- private void forwardPacket(OFPacketIn pi, IOFSwitch sw, short port) {
- List<OFAction> actions = new ArrayList<OFAction>(1);
- actions.add(new OFActionOutput(port));
+ private OFPacketOut constructPacketOut(DataPath datapath, OFPacketIn pi,
+ IOFSwitch sw) {
+ //List<OFAction> actions = new ArrayList<OFAction>(1);
+ //actions.add(new OFActionOutput(port));
OFPacketOut po = new OFPacketOut();
po.setInPort(OFPort.OFPP_NONE)
.setInPort(pi.getInPort())
- .setActions(actions)
- .setActionsLength((short)OFActionOutput.MINIMUM_LENGTH)
- .setLengthU(OFPacketOut.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
+ .setActions(new ArrayList<OFAction>())
+ .setLengthU(OFPacketOut.MINIMUM_LENGTH);
if (sw.getBuffers() == 0) {
po.setBufferId(OFPacketOut.BUFFER_ID_NONE)
@@ -306,11 +359,45 @@
po.setBufferId(pi.getBufferId());
}
- try {
- sw.write(po, null);
- sw.flush();
- } catch (IOException e) {
- log.error("Error writing packet out to switch: {}", e);
+ return po;
+ }
+
+ @Override
+ public void flowsInstalled(Collection<FlowPath> installedFlowPaths) {
+ for (FlowPath flowPath : installedFlowPaths) {
+ flowInstalled(flowPath);
+ }
+ }
+
+ private void flowInstalled(FlowPath installedFlowPath) {
+ // TODO check concurrency
+ // will need to sync and access both collections at once.
+ long flowId = installedFlowPath.flowId().value();
+ Collection<PacketToPush> packets = waitingPackets.removeAll(flowId);
+
+ //remove pending flows entry
+ Path pathToRemove = new Path(installedFlowPath.dataPath().srcPort(),
+ installedFlowPath.dataPath().dstPort());
+ pendingFlows.remove(pathToRemove);
+
+ for (PacketToPush packet : packets) {
+ IOFSwitch sw = floodlightProvider.getSwitches().get(packet.dpid);
+
+ OFPacketOut po = packet.packet;
+ short outPort =
+ installedFlowPath.flowEntries().get(0).outPort().value();
+ po.getActions().add(new OFActionOutput(outPort));
+ po.setActionsLength((short)
+ (po.getActionsLength() + OFActionOutput.MINIMUM_LENGTH));
+ po.setLengthU(po.getLengthU() + OFActionOutput.MINIMUM_LENGTH);
+
+ try {
+ sw.write(packet.packet, null);
+ sw.flush();
+ } catch (IOException e) {
+ log.error("Error writing packet out to switch {}:",
+ sw.getId(), e);
+ }
}
}
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
new file mode 100644
index 0000000..e5bd714
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
@@ -0,0 +1,25 @@
+package net.onrc.onos.ofcontroller.forwarding;
+
+import java.util.Collection;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+
+/**
+ * Temporary interface that allows the Forwarding module to be
+ * notified when a flow has been installed by the FlowManager.
+ *
+ * This should be refactored to a listener framework in the future.
+ * @author jono
+ *
+ */
+public interface IForwardingService extends IFloodlightService {
+ /**
+ * Notify the Forwarding module that a collection of flows has been
+ * installed in the network.
+ *
+ * @param installedFlowPaths the collection of FlowPaths that have
+ * been installed in the network.
+ */
+ public void flowsInstalled(Collection<FlowPath> installedFlowPaths);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
index 6ce5ade..ee8f23d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
@@ -2,11 +2,7 @@
import java.io.Serializable;
import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-
import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.util.SwitchPort;
public class ArpMessage implements Serializable {
@@ -25,9 +21,8 @@
private final long outSwitch;
private final short outPort;
-
- private final List<SwitchPort> switchPorts = new ArrayList<SwitchPort>();
-
+
+
public enum Type {
REQUEST,
REPLY
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 b2b3c48..c53e8e1 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -394,6 +394,7 @@
}
+ @SuppressWarnings("unused")
private void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp){
if (log.isTraceEnabled()) {
log.trace("ARP reply recieved: {} => {}, on {}/{}", new Object[] {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/ITopologyNetService.java b/src/main/java/net/onrc/onos/ofcontroller/topology/ITopologyNetService.java
index 9585366..4269eac 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/ITopologyNetService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/ITopologyNetService.java
@@ -1,7 +1,5 @@
package net.onrc.onos.ofcontroller.topology;
-import java.util.Map;
-
import net.floodlightcontroller.core.module.IFloodlightService;
import net.onrc.onos.ofcontroller.util.DataPath;
import net.onrc.onos.ofcontroller.util.SwitchPort;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
index dbf9ada..fc75591 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -265,6 +265,9 @@
break;
}
+ case ELEMENT_UNKNOWN:
+ // TODO: Adding "assert(false);" here can be dangerous
+ break;
}
return isModified;
@@ -315,6 +318,9 @@
}
break;
}
+ case ELEMENT_UNKNOWN:
+ // TODO: Adding "assert(false);" here can be dangerous
+ break;
}
return isModified;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyElement.java b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyElement.java
index b01c7d3..0fefa3a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyElement.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyElement.java
@@ -1,8 +1,5 @@
package net.onrc.onos.ofcontroller.topology;
-import java.util.Map;
-import java.util.TreeMap;
-
/**
* Class for storing information about a Topology Element: Switch, Port or
* Link.
@@ -165,6 +162,8 @@
return "Link=" +
Long.toHexString(fromSwitchDpid) + "/" + fromSwitchPort + "/" +
Long.toHexString(toSwitchDpid) + "/" + toSwitchPort;
+ case ELEMENT_UNKNOWN:
+ return "Element=UNKNOWN";
}
assert(false);
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 c0e04f2..02e0ffb 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -225,8 +225,12 @@
SwitchPort dest = flowPath.dataPath().dstPort();
return ShortestPath.getTopologyShortestPath(topology, src, dest);
}
+
case FP_TYPE_EXPLICIT_PATH:
return flowPath.dataPath();
+
+ case FP_TYPE_UNKNOWN:
+ return null;
}
return null;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java b/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
index 0d33b27..d8997dc 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
@@ -2,7 +2,6 @@
import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
-import net.onrc.onos.ofcontroller.topology.TopologyManager;
import net.onrc.onos.ofcontroller.util.DataPath;
import net.onrc.onos.ofcontroller.util.Dpid;
import net.onrc.onos.ofcontroller.util.Port;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
index 98dbd88..c8b206f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
@@ -13,6 +13,8 @@
public class FlowEntry {
private FlowId flowId; // FlowID of the Flow Entry
private FlowEntryId flowEntryId; // The Flow Entry ID
+ private int idleTimeout; // The Flow idle timeout
+ private int hardTimeout; // The Flow hard timeout
private FlowEntryMatch flowEntryMatch; // The Flow Entry Match
private FlowEntryActions flowEntryActions; // The Flow Entry Actions
private Dpid dpid; // The Switch DPID
@@ -174,6 +176,54 @@
}
/**
+ * Get the flow idle timeout in seconds.
+ *
+ * It should be an unsigned integer in the interval [0, 65535].
+ * If zero, the timeout is not set.
+ *
+ * @return the flow idle timeout.
+ */
+ @JsonProperty("idleTimeout")
+ public int idleTimeout() { return idleTimeout; }
+
+ /**
+ * Set the flow idle timeout in seconds.
+ *
+ * It should be an unsigned integer in the interval [0, 65535].
+ * If zero, the timeout is not set.
+ *
+ * @param idleTimeout the flow idle timeout to set.
+ */
+ @JsonProperty("idleTimeout")
+ public void setIdleTimeout(int idleTimeout) {
+ this.idleTimeout = 0xffff & idleTimeout;
+ }
+
+ /**
+ * Get the flow hard timeout in seconds.
+ *
+ * It should be an unsigned integer in the interval [0, 65535].
+ * If zero, the timeout is not set.
+ *
+ * @return the flow hard timeout.
+ */
+ @JsonProperty("hardTimeout")
+ public int hardTimeout() { return hardTimeout; }
+
+ /**
+ * Set the flow hard timeout in seconds.
+ *
+ * It should be an unsigned integer in the interval [0, 65535].
+ * If zero, the timeout is not set.
+ *
+ * @param hardTimeout the flow hard timeout to set.
+ */
+ @JsonProperty("hardTimeout")
+ public void setHardTimeout(int hardTimeout) {
+ this.hardTimeout = 0xffff & hardTimeout;
+ }
+
+ /**
* Get the Flow Entry Match.
*
* @return the Flow Entry Match.
@@ -343,7 +393,8 @@
* Convert the flow entry to a string.
*
* The string has the following form:
- * [flowEntryId=XXX flowEntryMatch=XXX flowEntryActions=XXX dpid=XXX
+ * [flowEntryId=XXX idleTimeout=XXX hardTimeout=XXX
+ * flowEntryMatch=XXX flowEntryActions=XXX dpid=XXX
* inPort=XXX outPort=XXX flowEntryUserState=XXX flowEntrySwitchState=XXX
* flowEntryErrorState=XXX]
* @return the flow entry as a string.
@@ -359,10 +410,12 @@
if ( flowId != null ) {
ret.append(" flowId=" + this.flowId.toString());
}
+ ret.append(" idleTimeout=" + this.idleTimeout);
+ ret.append(" hardTimeout=" + this.hardTimeout);
if ( flowEntryMatch != null ) {
ret.append(" flowEntryMatch=" + this.flowEntryMatch.toString());
}
- ret.append( " flowEntryActions=" + this.flowEntryActions.toString() );
+ ret.append(" flowEntryActions=" + this.flowEntryActions.toString() );
if ( dpid != null ) {
ret.append(" dpid=" + this.dpid.toString());
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java
index a1163c8..e431f8a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java
@@ -43,6 +43,13 @@
private ActionValues(short value) {
this.value = value;
}
+
+ /**
+ * Get the value.
+ *
+ * @return the value.
+ */
+ public short getValue() { return value; }
}
/**
@@ -1564,6 +1571,9 @@
case ACTION_ENQUEUE:
ret += " action=" + actionEnqueue.toString();
break;
+ case ACTION_VENDOR:
+ ret += " action=VENDOR";
+ break;
}
ret += "]";
@@ -1656,6 +1666,9 @@
case ACTION_ENQUEUE:
actionEnqueue = new ActionEnqueue(decode);
break;
+ case ACTION_VENDOR:
+ // TODO: Handle it as appropriate
+ break;
}
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid action string");
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java
index ab3edb1..7c87a10 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java
@@ -18,7 +18,9 @@
private FlowPathType flowPathType; // The Flow Path type
private FlowPathUserState flowPathUserState; // The Flow Path User state
private FlowPathFlags flowPathFlags; // The Flow Path flags
- private DataPath dataPath; // The data path
+ private int idleTimeout; // The Flow idle timeout
+ private int hardTimeout; // The Flow hard timeout
+ private DataPath dataPath; // The data path
private FlowEntryMatch flowEntryMatch; // Common Flow Entry Match for all
// Flow Entries
private FlowEntryActions flowEntryActions; // The Flow Entry Actions for
@@ -45,6 +47,8 @@
this.setFlowPathType(FlowPathType.valueOf(flowObj.getFlowPathType()));
this.setFlowPathUserState(FlowPathUserState.valueOf(flowObj.getFlowPathUserState()));
this.setFlowPathFlags(new FlowPathFlags(flowObj.getFlowPathFlags()));
+ this.setIdleTimeout(flowObj.getIdleTimeout());
+ this.setHardTimeout(flowObj.getHardTimeout());
this.dataPath().srcPort().setDpid(new Dpid(flowObj.getSrcSwitch()));
this.dataPath().srcPort().setPort(new Port(flowObj.getSrcPort()));
this.dataPath().dstPort().setDpid(new Dpid(flowObj.getDstSwitch()));
@@ -295,6 +299,54 @@
}
/**
+ * Get the flow idle timeout in seconds.
+ *
+ * It should be an unsigned integer in the interval [0, 65535].
+ * If zero, the timeout is not set.
+ *
+ * @return the flow idle timeout.
+ */
+ @JsonProperty("idleTimeout")
+ public int idleTimeout() { return idleTimeout; }
+
+ /**
+ * Set the flow idle timeout in seconds.
+ *
+ * It should be an unsigned integer in the interval [0, 65535].
+ * If zero, the timeout is not set.
+ *
+ * @param idleTimeout the flow idle timeout to set.
+ */
+ @JsonProperty("idleTimeout")
+ public void setIdleTimeout(int idleTimeout) {
+ this.idleTimeout = 0xffff & idleTimeout;
+ }
+
+ /**
+ * Get the flow hard timeout in seconds.
+ *
+ * It should be an unsigned integer in the interval [0, 65535].
+ * If zero, the timeout is not set.
+ *
+ * @return the flow hard timeout.
+ */
+ @JsonProperty("hardTimeout")
+ public int hardTimeout() { return hardTimeout; }
+
+ /**
+ * Set the flow hard timeout.
+ *
+ * It should be an unsigned integer in the interval [0, 65535].
+ * If zero, the timeout is not set.
+ *
+ * @param hardTimeout the flow hard timeout to set.
+ */
+ @JsonProperty("hardTimeout")
+ public void setHardTimeout(int hardTimeout) {
+ this.hardTimeout = 0xffff & hardTimeout;
+ }
+
+ /**
* Get the flow path's data path.
*
* @return the flow path's data path.
@@ -366,8 +418,8 @@
*
* The string has the following form:
* [flowId=XXX installerId=XXX flowPathType = XXX flowPathUserState = XXX
- * flowPathFlags=XXX dataPath=XXX flowEntryMatch=XXX
- * flowEntryActions=XXX]
+ * flowPathFlags=XXX idleTimeout=XXX hardTimeout=XXX dataPath=XXX
+ * flowEntryMatch=XXX flowEntryActions=XXX]
*
* @return the flow path as a string.
*/
@@ -378,6 +430,8 @@
ret += " flowPathType=" + this.flowPathType;
ret += " flowPathUserState=" + this.flowPathUserState;
ret += " flowPathFlags=" + this.flowPathFlags.toString();
+ ret += " idleTimeout=" + this.idleTimeout;
+ ret += " hardTimeout=" + this.hardTimeout;
if (dataPath != null)
ret += " dataPath=" + this.dataPath.toString();
if (flowEntryMatch != null)
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java
index 4bbd399..595eb5f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java
@@ -112,8 +112,6 @@
// Test all flags
if ((this.flags & DISCARD_FIRST_HOP_ENTRY) != 0) {
- if (flagsStr != null)
- flagsStr += ",";
flagsStr += "DISCARD_FIRST_HOP_ENTRY";
}
if ((this.flags & KEEP_ONLY_FIRST_HOP_ENTRY) != 0) {
@@ -121,6 +119,8 @@
flagsStr += ",";
flagsStr += "KEEP_ONLY_FIRST_HOP_ENTRY";
}
+ if (flagsStr != null)
+ ret += flagsStr;
ret += "]";
return ret;
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index 8b6bde7..4a60d2a 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -5,10 +5,6 @@
net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager
net.floodlightcontroller.topology.TopologyManager
net.floodlightcontroller.forwarding.Forwarding
-net.floodlightcontroller.flowcache.FlowReconcileManager
-net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher
-net.floodlightcontroller.perfmon.PktInProcessingTime
-net.floodlightcontroller.perfmon.NullPktInProcessingTime
net.floodlightcontroller.restserver.RestApiServer
net.floodlightcontroller.counter.CounterStore
net.floodlightcontroller.counter.NullCounterStore
diff --git a/src/main/resources/hazelcast.xml b/src/main/resources/hazelcast.xml
new file mode 120000
index 0000000..f8f4972
--- /dev/null
+++ b/src/main/resources/hazelcast.xml
@@ -0,0 +1 @@
+/home/mininet/ONOS/conf/hazelcast.xml
\ No newline at end of file
diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index 4c9c340..fcdbcf0 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -61,8 +61,6 @@
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPacket;
import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
-import net.floodlightcontroller.perfmon.PktInProcessingTime;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.restserver.RestApiServer;
import net.floodlightcontroller.storage.IStorageSourceService;
@@ -132,9 +130,7 @@
CounterStore cs = new CounterStore();
fmc.addService(ICounterStoreService.class, cs);
- PktInProcessingTime ppt = new PktInProcessingTime();
- fmc.addService(IPktInProcessingTimeService.class, ppt);
-
+
tp = new MockThreadPoolService();
fmc.addService(IThreadPoolService.class, tp);
@@ -148,14 +144,12 @@
fmc.addService(ILinkDiscoveryService.class, linkDiscovery);
- ppt.init(fmc);
restApi.init(fmc);
memstorage.init(fmc);
cm.init(fmc);
tp.init(fmc);
sr.init(fmc);
linkDiscovery.init(fmc);
- ppt.startUp(fmc);
restApi.startUp(fmc);
memstorage.startUp(fmc);
cm.startUp(fmc);
diff --git a/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java b/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java
index be43a8b..716c7da 100644
--- a/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java
+++ b/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java
@@ -4,20 +4,17 @@
import java.util.Collection;
import java.util.Iterator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.module.FloodlightModuleLoader;
-import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.test.MockFloodlightProvider;
import net.floodlightcontroller.core.test.MockThreadPoolService;
import net.floodlightcontroller.counter.NullCounterStore;
import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
-import net.floodlightcontroller.perfmon.NullPktInProcessingTime;
import net.floodlightcontroller.storage.memory.MemoryStorageSource;
import net.floodlightcontroller.topology.TopologyManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
public class FloodlightTestModuleLoader extends FloodlightModuleLoader {
protected final static Logger log = LoggerFactory.getLogger(FloodlightTestModuleLoader.class);
@@ -36,8 +33,7 @@
MockThreadPoolService.class;
public static final Class<? extends IFloodlightModule> DEFAULT_ENTITY_CLASSIFIER =
DefaultEntityClassifier.class;
- public static final Class<? extends IFloodlightModule> DEFAULT_PERFMON =
- NullPktInProcessingTime.class;
+
protected static final Collection<Class<? extends IFloodlightModule>> DEFAULT_MODULE_LIST;
@@ -50,7 +46,7 @@
DEFAULT_MODULE_LIST.add(DEFAULT_COUNTER_STORE);
DEFAULT_MODULE_LIST.add(DEFAULT_THREADPOOL);
DEFAULT_MODULE_LIST.add(DEFAULT_ENTITY_CLASSIFIER);
- DEFAULT_MODULE_LIST.add(DEFAULT_PERFMON);
+
}
protected IFloodlightModuleContext fmc;
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
index 7afb78a..eb84b42 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
@@ -48,8 +48,6 @@
import net.floodlightcontroller.devicemanager.test.MockEntityClassifier;
import net.floodlightcontroller.devicemanager.test.MockEntityClassifierMac;
import net.floodlightcontroller.devicemanager.test.MockFlexEntityClassifier;
-import net.floodlightcontroller.flowcache.FlowReconcileManager;
-import net.floodlightcontroller.flowcache.IFlowReconcileService;
import net.floodlightcontroller.packet.ARP;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPacket;
@@ -90,7 +88,7 @@
MockFloodlightProvider mockFloodlightProvider;
DeviceManagerImpl deviceManager;
MemoryStorageSource storageSource;
- FlowReconcileManager flowReconcileMgr;
+
private IOFSwitch makeSwitchMock(long id) {
IOFSwitch mockSwitch = createMock(IOFSwitch.class);
@@ -115,25 +113,25 @@
fmc.addService(IThreadPoolService.class, tp);
mockFloodlightProvider = getMockFloodlightProvider();
deviceManager = new DeviceManagerImpl();
- flowReconcileMgr = new FlowReconcileManager();
+
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(IFlowReconcileService.class, flowReconcileMgr);
+
fmc.addService(IEntityClassifierService.class, entityClassifier);
fmc.addService(ITopologyService.class, topology);
tp.init(fmc);
restApi.init(fmc);
storageSource.init(fmc);
deviceManager.init(fmc);
- flowReconcileMgr.init(fmc);
+
entityClassifier.init(fmc);
storageSource.startUp(fmc);
deviceManager.startUp(fmc);
- flowReconcileMgr.startUp(fmc);
+
tp.startUp(fmc);
entityClassifier.startUp(fmc);
diff --git a/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java b/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java
deleted file mode 100644
index 0427828..0000000
--- a/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java
+++ /dev/null
@@ -1,500 +0,0 @@
-package net.floodlightcontroller.flowcache;
-
-import static org.easymock.EasyMock.*;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.ListIterator;
-
-import net.floodlightcontroller.core.IListener.Command;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.counter.SimpleCounter;
-import net.floodlightcontroller.counter.CounterValue.CounterType;
-import net.floodlightcontroller.flowcache.IFlowReconcileListener;
-import net.floodlightcontroller.flowcache.OFMatchReconcile;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.OFType;
-
-public class FlowReconcileMgrTest extends FloodlightTestCase {
-
- protected MockFloodlightProvider mockFloodlightProvider;
- protected FlowReconcileManager flowReconcileMgr;
- protected MockThreadPoolService threadPool;
- protected ICounterStoreService counterStore;
- protected FloodlightModuleContext fmc;
-
- OFStatisticsRequest ofStatsRequest;
-
- protected int NUM_FLOWS_PER_THREAD = 100;
- protected int NUM_THREADS = 100;
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- fmc = new FloodlightModuleContext();
- flowReconcileMgr = new FlowReconcileManager();
- threadPool = new MockThreadPoolService();
- counterStore = createMock(ICounterStoreService.class);
-
- fmc.addService(ICounterStoreService.class, counterStore);
- fmc.addService(IThreadPoolService.class, threadPool);
-
- threadPool.init(fmc);
- flowReconcileMgr.init(fmc);
-
- threadPool.startUp(fmc);
- flowReconcileMgr.startUp(fmc);
- }
-
- /** Verify pipeline listener registration and ordering
- *
- * @throws Exception
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testFlowReconcilePipeLine() throws Exception {
- flowReconcileMgr.flowReconcileEnabled = true;
-
- IFlowReconcileListener r1 =
- EasyMock.createNiceMock(IFlowReconcileListener.class);
- IFlowReconcileListener r2 =
- EasyMock.createNiceMock(IFlowReconcileListener.class);
- IFlowReconcileListener r3 =
- EasyMock.createNiceMock(IFlowReconcileListener.class);
-
- expect(r1.getName()).andReturn("r1").anyTimes();
- expect(r2.getName()).andReturn("r2").anyTimes();
- expect(r3.getName()).andReturn("r3").anyTimes();
-
- // Set the listeners' order: r1 -> r2 -> r3
- expect(r1.isCallbackOrderingPrereq((OFType)anyObject(),
- (String)anyObject())).andReturn(false).anyTimes();
- expect(r1.isCallbackOrderingPostreq((OFType)anyObject(),
- (String)anyObject())).andReturn(false).anyTimes();
- expect(r2.isCallbackOrderingPrereq((OFType)anyObject(),
- eq("r1"))).andReturn(true).anyTimes();
- expect(r2.isCallbackOrderingPrereq((OFType)anyObject(),
- eq("r3"))).andReturn(false).anyTimes();
- expect(r2.isCallbackOrderingPostreq((OFType)anyObject(),
- eq("r1"))).andReturn(false).anyTimes();
- expect(r2.isCallbackOrderingPostreq((OFType)anyObject(),
- eq("r3"))).andReturn(true).anyTimes();
- expect(r3.isCallbackOrderingPrereq((OFType)anyObject(),
- eq("r1"))).andReturn(false).anyTimes();
- expect(r3.isCallbackOrderingPrereq((OFType)anyObject(),
- eq("r2"))).andReturn(true).anyTimes();
- expect(r3.isCallbackOrderingPostreq((OFType)anyObject(),
- (String)anyObject())).andReturn(false).anyTimes();
-
- expect(r1.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject())).
- andThrow(new RuntimeException("This is NOT an error! " +
- "We are testing exception catching."));
-
- SimpleCounter cnt = (SimpleCounter)SimpleCounter.createCounter(
- new Date(),
- CounterType.LONG);
- cnt.increment();
- expect(counterStore.getCounter(
- flowReconcileMgr.controllerPktInCounterName))
- .andReturn(cnt)
- .anyTimes();
-
- replay(r1, r2, r3, counterStore);
- flowReconcileMgr.clearFlowReconcileListeners();
- flowReconcileMgr.addFlowReconcileListener(r1);
- flowReconcileMgr.addFlowReconcileListener(r2);
- flowReconcileMgr.addFlowReconcileListener(r3);
-
- int pre_flowReconcileThreadRunCount =
- flowReconcileMgr.flowReconcileThreadRunCount;
- Date startTime = new Date();
- OFMatchReconcile ofmRcIn = new OFMatchReconcile();
- try {
- flowReconcileMgr.reconcileFlow(ofmRcIn);
- flowReconcileMgr.doReconcile();
- } catch (RuntimeException e) {
- assertEquals(e.getMessage()
- .startsWith("This is NOT an error!"), true);
- }
-
- verify(r1, r2, r3);
-
- // verify STOP works
- reset(r1, r2, r3);
-
- // restart reconcileThread since it exited due to previous runtime
- // exception.
- flowReconcileMgr.startUp(fmc);
- expect(r1.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.STOP).times(1);
- expect(r2.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()));
- expectLastCall().andAnswer(new IAnswer<Object>() {
- public Object answer() {
- fail("Unexpected call");
- return Command.STOP;
- }
- }).anyTimes();
-
- pre_flowReconcileThreadRunCount =
- flowReconcileMgr.flowReconcileThreadRunCount;
- startTime = new Date();
- replay(r1, r2, r3);
- flowReconcileMgr.reconcileFlow(ofmRcIn);
- while (flowReconcileMgr.flowReconcileThreadRunCount <=
- pre_flowReconcileThreadRunCount) {
- Thread.sleep(10);
- Date currTime = new Date();
- assertTrue((currTime.getTime() - startTime.getTime()) < 1000);
- }
- verify(r1, r2, r3);
-
- // verify CONTINUE works
- reset(r1, r2, r3);
- expect(r1.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.CONTINUE).times(1);
- expect(r2.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.STOP).times(1);
- expect(r3.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()));
- expectLastCall().andAnswer(new IAnswer<Object>() {
- public Object answer() {
- fail("Unexpected call");
- return Command.STOP;
- }
- }).anyTimes();
-
- pre_flowReconcileThreadRunCount =
- flowReconcileMgr.flowReconcileThreadRunCount;
- startTime = new Date();
-
- replay(r1, r2, r3);
- flowReconcileMgr.reconcileFlow(ofmRcIn);
- while (flowReconcileMgr.flowReconcileThreadRunCount <=
- pre_flowReconcileThreadRunCount) {
- Thread.sleep(10);
- Date currTime = new Date();
- assertTrue((currTime.getTime() - startTime.getTime()) < 1000);
- }
- verify(r1, r2, r3);
-
- // verify CONTINUE works
- reset(r1, r2, r3);
- expect(r1.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.CONTINUE).times(1);
- expect(r2.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.CONTINUE).times(1);
- expect(r3.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.STOP).times(1);
-
- pre_flowReconcileThreadRunCount =
- flowReconcileMgr.flowReconcileThreadRunCount;
- startTime = new Date();
-
- replay(r1, r2, r3);
- flowReconcileMgr.reconcileFlow(ofmRcIn);
- while (flowReconcileMgr.flowReconcileThreadRunCount <=
- pre_flowReconcileThreadRunCount) {
- Thread.sleep(10);
- Date currTime = new Date();
- assertTrue((currTime.getTime() - startTime.getTime()) < 1000);
- }
- verify(r1, r2, r3);
-
- // Verify removeFlowReconcileListener
- flowReconcileMgr.removeFlowReconcileListener(r1);
- reset(r1, r2, r3);
- expect(r1.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()));
- expectLastCall().andAnswer(new IAnswer<Object>() {
- public Object answer() {
- fail("Unexpected call to a listener that is " +
- "removed from the chain.");
- return Command.STOP;
- }
- }).anyTimes();
- expect(r2.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.CONTINUE).times(1);
- expect(r3.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.STOP).times(1);
-
- pre_flowReconcileThreadRunCount =
- flowReconcileMgr.flowReconcileThreadRunCount;
- startTime = new Date();
- replay(r1, r2, r3);
- flowReconcileMgr.reconcileFlow(ofmRcIn);
- while (flowReconcileMgr.flowReconcileThreadRunCount <=
- pre_flowReconcileThreadRunCount) {
- Thread.sleep(10);
- Date currTime = new Date();
- assertTrue((currTime.getTime() - startTime.getTime()) < 1000);
- }
- verify(r1, r2, r3);
- }
-
- @Test
- public void testGetPktInRate() {
- internalTestGetPktInRate(CounterType.LONG);
- internalTestGetPktInRate(CounterType.DOUBLE);
- }
-
- protected void internalTestGetPktInRate(CounterType type) {
- Date currentTime = new Date();
- SimpleCounter newCnt = (SimpleCounter)SimpleCounter.createCounter(
- currentTime, type);
- newCnt.increment(currentTime, 1);
-
- // Set the lastCounter time in the future of the current time
- Date lastCounterTime = new Date(currentTime.getTime() + 1000);
- flowReconcileMgr.lastPacketInCounter =
- (SimpleCounter)SimpleCounter.createCounter(
- lastCounterTime, type);
- flowReconcileMgr.lastPacketInCounter.increment(lastCounterTime, 1);
-
- assertEquals(FlowReconcileManager.MAX_SYSTEM_LOAD_PER_SECOND,
- flowReconcileMgr.getPktInRate(newCnt, new Date()));
-
- // Verify the rate == 0 time difference is zero.
- lastCounterTime = new Date(currentTime.getTime() - 1000);
- flowReconcileMgr.lastPacketInCounter.increment(lastCounterTime, 1);
- assertEquals(0, flowReconcileMgr.getPktInRate(newCnt, lastCounterTime));
-
- /** verify the computation is correct.
- * new = 2000, old = 1000, Tdiff = 1 second.
- * rate should be 1000/second
- */
- newCnt = (SimpleCounter)SimpleCounter.createCounter(
- currentTime, type);
- newCnt.increment(currentTime, 2000);
-
- lastCounterTime = new Date(currentTime.getTime() - 1000);
- flowReconcileMgr.lastPacketInCounter =
- (SimpleCounter)SimpleCounter.createCounter(
- lastCounterTime, type);
- flowReconcileMgr.lastPacketInCounter.increment(lastCounterTime, 1000);
- assertEquals(1000, flowReconcileMgr.getPktInRate(newCnt, currentTime));
-
- /** verify the computation is correct.
- * new = 2,000,000, old = 1,000,000, Tdiff = 2 second.
- * rate should be 1000/second
- */
- newCnt = (SimpleCounter)SimpleCounter.createCounter(
- currentTime, type);
- newCnt.increment(currentTime, 2000000);
-
- lastCounterTime = new Date(currentTime.getTime() - 2000);
- flowReconcileMgr.lastPacketInCounter =
- (SimpleCounter)SimpleCounter.createCounter(
- lastCounterTime, type);
- flowReconcileMgr.lastPacketInCounter.increment(lastCounterTime,
- 1000000);
- assertEquals(500000, flowReconcileMgr.getPktInRate(newCnt,
- currentTime));
- }
-
- @Test
- public void testGetCurrentCapacity() throws Exception {
- // Disable the reconcile thread.
- flowReconcileMgr.flowReconcileEnabled = false;
-
- int minFlows = FlowReconcileManager.MIN_FLOW_RECONCILE_PER_SECOND *
- FlowReconcileManager.FLOW_RECONCILE_DELAY_MILLISEC / 1000;
-
- /** Verify the initial state, when packetIn counter has not
- * been created.
- */
- expect(counterStore.getCounter(
- flowReconcileMgr.controllerPktInCounterName))
- .andReturn(null)
- .times(1);
-
- replay(counterStore);
- assertEquals(minFlows, flowReconcileMgr.getCurrentCapacity());
- verify(counterStore);
-
- /** Verify the initial state, when lastPacketInCounter is null */
- reset(counterStore);
- Date currentTime = new Date();
- SimpleCounter newCnt = (SimpleCounter)SimpleCounter.createCounter(
- currentTime, CounterType.LONG);
-
- expect(counterStore.getCounter(
- flowReconcileMgr.controllerPktInCounterName))
- .andReturn(newCnt)
- .times(1);
- long initPktInCount = 10000;
- newCnt.increment(currentTime, initPktInCount);
-
- replay(counterStore);
- assertEquals(minFlows, flowReconcileMgr.getCurrentCapacity());
- verify(counterStore);
-
- /** Now the lastPacketInCounter has been set.
- * lastCounter = 100,000 and newCounter = 300,000, t = 1 second
- * packetInRate = 200,000/sec.
- * capacity should be 500k - 200k = 300k
- */
- reset(counterStore);
- newCnt = (SimpleCounter)SimpleCounter.createCounter(
- currentTime, CounterType.LONG);
- currentTime = new Date(currentTime.getTime() + 200);
- long nextPktInCount = 30000;
- newCnt.increment(currentTime, nextPktInCount);
-
- expect(counterStore.getCounter(
- flowReconcileMgr.controllerPktInCounterName))
- .andReturn(newCnt)
- .times(1);
-
- replay(counterStore);
- // Wait for 1 second so that enough elapsed time to compute capacity.
- Thread.sleep(1000);
- int capacity = flowReconcileMgr.getCurrentCapacity();
- verify(counterStore);
- long expectedCap = (FlowReconcileManager.MAX_SYSTEM_LOAD_PER_SECOND -
- (nextPktInCount - initPktInCount)) *
- FlowReconcileManager.FLOW_RECONCILE_DELAY_MILLISEC / 1000;
- assertEquals(expectedCap, capacity);
- }
-
- private class FlowReconcileWorker implements Runnable {
- @Override
- public void run() {
- OFMatchReconcile ofmRc = new OFMatchReconcile();
- // push large number of flows to be reconciled.
- for (int i = 0; i < NUM_FLOWS_PER_THREAD; i++) {
- flowReconcileMgr.reconcileFlow(ofmRc);
- }
- }
- }
-
- /** Verify the flows are sent to the reconcile pipeline in order.
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testQueueFlowsOrder() {
- flowReconcileMgr.flowReconcileEnabled = false;
-
- IFlowReconcileListener r1 =
- EasyMock.createNiceMock(IFlowReconcileListener.class);
-
- expect(r1.getName()).andReturn("r1").anyTimes();
-
- // Set the listeners' order: r1 -> r2 -> r3
- expect(r1.isCallbackOrderingPrereq((OFType)anyObject(),
- (String)anyObject())).andReturn(false).anyTimes();
- expect(r1.isCallbackOrderingPostreq((OFType)anyObject(),
- (String)anyObject())).andReturn(false).anyTimes();
-
- expect(r1.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andAnswer(new IAnswer<Command>() {
- @Override
- public Command answer() throws Throwable {
- ArrayList<OFMatchReconcile> ofmList =
- (ArrayList<OFMatchReconcile>)EasyMock.
- getCurrentArguments()[0];
- ListIterator<OFMatchReconcile> lit = ofmList.listIterator();
- int index = 0;
- while (lit.hasNext()) {
- OFMatchReconcile ofm = lit.next();
- assertEquals(index++, ofm.cookie);
- }
- return Command.STOP;
- }
- }).times(1);
-
- SimpleCounter cnt = (SimpleCounter)SimpleCounter.createCounter(
- new Date(),
- CounterType.LONG);
- cnt.increment();
- expect(counterStore.getCounter(
- flowReconcileMgr.controllerPktInCounterName))
- .andReturn(cnt)
- .anyTimes();
-
- replay(r1, counterStore);
- flowReconcileMgr.clearFlowReconcileListeners();
- flowReconcileMgr.addFlowReconcileListener(r1);
-
- OFMatchReconcile ofmRcIn = new OFMatchReconcile();
- int index = 0;
- for (index = 0; index < 10; index++) {
- ofmRcIn.cookie = index;
- flowReconcileMgr.reconcileFlow(ofmRcIn);
- }
- flowReconcileMgr.flowReconcileEnabled = true;
- flowReconcileMgr.doReconcile();
-
- verify(r1);
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testQueueFlowsByManyThreads() {
- // Disable the reconcile thread so that the queue won't be emptied.
- flowQueueTest(false);
-
- // Enable the reconcile thread. The queue should be empty.
- Date currentTime = new Date();
- SimpleCounter newCnt = (SimpleCounter)SimpleCounter.createCounter(
- currentTime, CounterType.LONG);
-
- expect(counterStore.getCounter(
- flowReconcileMgr.controllerPktInCounterName))
- .andReturn(newCnt)
- .anyTimes();
- long initPktInCount = 10000;
- newCnt.increment(currentTime, initPktInCount);
-
- IFlowReconcileListener r1 =
- EasyMock.createNiceMock(IFlowReconcileListener.class);
-
- expect(r1.getName()).andReturn("r1").anyTimes();
-
- // Set the listeners' order: r1 -> r2 -> r3
- expect(r1.isCallbackOrderingPrereq((OFType)anyObject(),
- (String)anyObject())).andReturn(false).anyTimes();
- expect(r1.isCallbackOrderingPostreq((OFType)anyObject(),
- (String)anyObject())).andReturn(false).anyTimes();
-
- expect(r1.reconcileFlows((ArrayList<OFMatchReconcile>)anyObject()))
- .andReturn(Command.CONTINUE).anyTimes();
-
- flowReconcileMgr.clearFlowReconcileListeners();
- replay(r1, counterStore);
- flowQueueTest(true);
- verify(r1, counterStore);
- }
-
- protected void flowQueueTest(boolean enableReconcileThread) {
- flowReconcileMgr.flowReconcileEnabled = enableReconcileThread;
-
- // Simulate flow
- for (int i = 0; i < NUM_THREADS; i++) {
- Runnable worker = this.new FlowReconcileWorker();
- Thread t = new Thread(worker);
- t.start();
- }
-
- Date startTime = new Date();
- int totalFlows = NUM_THREADS * NUM_FLOWS_PER_THREAD;
- if (enableReconcileThread) {
- totalFlows = 0;
- }
- while (flowReconcileMgr.flowQueue.size() != totalFlows) {
- Date currTime = new Date();
- assertTrue((currTime.getTime() - startTime.getTime()) < 2000);
- }
-
- // Make sure all flows are in the queue.
- assertEquals(totalFlows, flowReconcileMgr.flowQueue.size());
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index 7a37589..3e262af 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -50,8 +50,6 @@
import net.floodlightcontroller.topology.ITopologyListener;
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.topology.NodePortTuple;
-import net.floodlightcontroller.flowcache.FlowReconcileManager;
-import net.floodlightcontroller.flowcache.IFlowReconcileService;
import net.floodlightcontroller.forwarding.Forwarding;
import org.easymock.Capture;
@@ -77,7 +75,6 @@
protected MockDeviceManager deviceManager;
protected IRoutingService routingEngine;
protected Forwarding forwarding;
- protected FlowReconcileManager flowReconcileMgr;
protected ITopologyService topology;
protected MockThreadPoolService threadPool;
protected IOFSwitch sw1, sw2;
@@ -121,7 +118,6 @@
forwarding = new Forwarding();
threadPool = new MockThreadPoolService();
deviceManager = new MockDeviceManager();
- flowReconcileMgr = new FlowReconcileManager();
routingEngine = createMock(IRoutingService.class);
topology = createMock(ITopologyService.class);
DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
@@ -135,7 +131,6 @@
fmc.addService(IRoutingService.class, routingEngine);
fmc.addService(ICounterStoreService.class, new CounterStore());
fmc.addService(IDeviceService.class, deviceManager);
- fmc.addService(IFlowReconcileService.class, flowReconcileMgr);
fmc.addService(IEntityClassifierService.class, entityClassifier);
topology.addListener(anyObject(ITopologyListener.class));
@@ -144,12 +139,10 @@
threadPool.init(fmc);
forwarding.init(fmc);
deviceManager.init(fmc);
- flowReconcileMgr.init(fmc);
entityClassifier.init(fmc);
threadPool.startUp(fmc);
deviceManager.startUp(fmc);
forwarding.startUp(fmc);
- flowReconcileMgr.startUp(fmc);
entityClassifier.startUp(fmc);
verify(topology);
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
index 06d8522..f1c2c71 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
@@ -78,6 +78,38 @@
flowEntry.setFlowEntryId(flowEntryId);
assertEquals(flowEntry.getFlowEntryId(), flowEntryId);
}
+
+ /**
+ * Desc:
+ * Test method for set and get Idle Timeout.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set Idle Timeout.
+ * 2. Should get Idle Timeout.
+ */
+ @Test
+ public void testSetGetIdleTimeout() {
+ Integer idleTimeout = 5;
+ flowEntry.setIdleTimeout(idleTimeout);
+ assertEquals(flowEntry.getIdleTimeout(), idleTimeout);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get Hard Timeout.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set Hard Timeout.
+ * 2. Should get Hard Timeout.
+ */
+ @Test
+ public void testSetGetHardTimeout() {
+ Integer hardTimeout = 5;
+ flowEntry.setHardTimeout(hardTimeout);
+ assertEquals(flowEntry.getHardTimeout(), hardTimeout);
+ }
/**
* Desc:
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
index 9a1e34a..39e4955 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
@@ -158,6 +158,42 @@
/**
* Desc:
+ * Test method for get and set Idle Timeout method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the Idle Timeout.
+ * 2. Should get the Idle Timeout.
+ */
+ @Test
+ public void testSetGetIdleTimeout() {
+ String flowId = "xx";
+ Integer idleTimeout = 5;
+ flowPath.setFlowId(flowId);
+ flowPath.setIdleTimeout(idleTimeout);
+ assertEquals(flowPath.getIdleTimeout(), idleTimeout);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set Hard Timeout method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the Hard Timeout.
+ * 2. Should get the Hard Timeout.
+ */
+ @Test
+ public void testSetGetHardTimeout() {
+ String flowId = "xx";
+ Integer hardTimeout = 5;
+ flowPath.setFlowId(flowId);
+ flowPath.setHardTimeout(hardTimeout);
+ assertEquals(flowPath.getHardTimeout(), hardTimeout);
+ }
+
+ /**
+ * Desc:
* Test method for get and set SourceSwitch method.
* Condition:
* N/A
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
index 4aea22a..8034d44 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
@@ -37,6 +37,7 @@
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
+@SuppressWarnings("serial")
public class LinkStorageImplTest {
protected final static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
@@ -519,7 +520,6 @@
* Create a mock {@link GraphDBOperation} which hooks port-related methods.
* @return EasyMock-wrapped GraphDBOperation object.
*/
- @SuppressWarnings("serial")
private GraphDBOperation createMockGraphDBOperation() {
GraphDBOperation mockDBOpe = EasyMock.createNiceMock(GraphDBOperation.class);
@@ -672,7 +672,6 @@
* @param dpid DPID of the switch
* @return List of port number
*/
- @SuppressWarnings("serial")
private List<Short> getPorts(long dpid) {
List<Short> ports;
@@ -699,7 +698,6 @@
* Returns list of DPIDs in test topology.
* @return List of DPIDs
*/
- @SuppressWarnings("serial")
private List<Long> getDpids() {
List<Long> dpids = new ArrayList<Long>() {{
add(Long.decode("0x0000000000000a01"));
@@ -726,12 +724,6 @@
return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
}
- // make NO sense while test-network data doesn't define physical network (i.e. any link is feasible)
- @SuppressWarnings("unused")
- private Link createInfeasibleLink() {
- return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a03"), 3);
- }
-
/**
* Returns list of existing {@link Link} objects
* @return ArrayList of new Link objects
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
index d7724ae..8da306f 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
@@ -326,6 +326,7 @@
* tests in net.onrc.onos.ofcontroller.core.*
*/
public static class TestDeviceObject implements IDeviceObject {
+ @SuppressWarnings("unused")
private String state,type,mac,ipaddr;
private List<IPortObject> ports;
private List<ISwitchObject> switches;
@@ -456,6 +457,8 @@
private String flowPathType;
private String flowPathUserState;
private Long flowPathFlags;
+ private Integer idleTimeout;
+ private Integer hardTimeout;
private String dataPathSummary;
private Short srcPort,dstPort;
private String matchSrcMac,matchDstMac;
@@ -474,6 +477,8 @@
private String flowPathTypeToUpdate;
private String flowPathUserStateToUpdate;
private Long flowPathFlagsToUpdate;
+ private Integer idleTimeoutToUpdate;
+ private Integer hardTimeoutToUpdate;
private String dataPathSummaryToUpdate;
private Short srcPortToUpdate,dstPortToUpdate;
private String matchSrcMacToUpdate,matchDstMacToUpdate;
@@ -514,6 +519,8 @@
if(flowPathTypeToUpdate != null) { flowPathType = flowPathTypeToUpdate; }
if(flowPathUserStateToUpdate != null) { flowPathUserState = flowPathUserStateToUpdate; }
if(flowPathFlagsToUpdate != null) { flowPathFlags = flowPathFlagsToUpdate; }
+ if(idleTimeoutToUpdate != null) { idleTimeout = idleTimeoutToUpdate; }
+ if(hardTimeoutToUpdate != null) { hardTimeout = hardTimeoutToUpdate; }
if(srcSwToUpdate != null) { srcSw = srcSwToUpdate; }
if(dstSwToUpdate != null) { dstSw = dstSwToUpdate; }
if(dataPathSummaryToUpdate != null) { dataPathSummary = dataPathSummaryToUpdate; }
@@ -545,6 +552,8 @@
flowPathTypeToUpdate = null;
flowPathUserStateToUpdate = null;
flowPathFlagsToUpdate = null;
+ idleTimeoutToUpdate = null;
+ hardTimeoutToUpdate = null;
srcSwToUpdate = dstSwToUpdate = dataPathSummaryToUpdate = null;
srcPortToUpdate = dstPortToUpdate = null;
matchSrcMacToUpdate = matchDstMacToUpdate = null;
@@ -565,6 +574,8 @@
public void setFlowPathTypeForTest(String flowPathType) { this.flowPathType = flowPathType; }
public void setFlowPathUserStateForTest(String flowPathUserState) { this.flowPathUserState = flowPathUserState; }
public void setFlowPathFlagsForTest(Long flowPathFlags) { this.flowPathFlags = flowPathFlags; }
+ public void setIdleTimeoutForTest(Integer idleTimeout) { this.idleTimeout = idleTimeout; }
+ public void setHardTimeoutForTest(Integer hardTimeout) { this.hardTimeout = hardTimeout; }
public void setSrcSwForTest(String srcSw) { this.srcSw = srcSw; }
public void setDstSwForTest(String dstSw) { this.dstSw = dstSw; }
public void setDataPathSummaryForTest(String dataPathSummary) { this.dataPathSummary = dataPathSummary; }
@@ -634,6 +645,18 @@
public void setFlowPathFlags(Long flowPathFlags) { flowPathFlagsToUpdate = flowPathFlags; }
@Override
+ public Integer getIdleTimeout() { return idleTimeout; }
+
+ @Override
+ public void setIdleTimeout(Integer idleTimeout) { idleTimeoutToUpdate = idleTimeout; }
+
+ @Override
+ public Integer getHardTimeout() { return hardTimeout; }
+
+ @Override
+ public void setHardTimeout(Integer hardTimeout) { hardTimeoutToUpdate = hardTimeout; }
+
+ @Override
public String getSrcSwitch() { return srcSw; }
@Override
@@ -768,6 +791,8 @@
public static class TestFlowEntry implements IFlowEntry {
private String state,type,entryId,dpid,userState,switchState,errorStateType,errorStateCode;
+ private Integer idleTimeout;
+ private Integer hardTimeout;
private Short matchInPort;
private String matchSrcMac,matchDstMac;
private Short matchEtherFrameType;
@@ -785,6 +810,8 @@
private String stateToUpdate,typeToUpdate,entryIdToUpdate,dpidToUpdate,
userStateToUpdate,switchStateToUpdate,errorStateTypeToUpdate,errorStateCodeToUpdate;
+ private Integer idleTimeoutToUpdate;
+ private Integer hardTimeoutToUpdate;
private Short matchInPortToUpdate;
private String matchSrcMacToUpdate,matchDstMacToUpdate;
private Short matchEtherFrameTypeToUpdate;
@@ -810,6 +837,8 @@
if(stateToUpdate != null) { state = stateToUpdate; }
if(typeToUpdate != null) { type = typeToUpdate; }
if(entryIdToUpdate != null) { entryId = entryIdToUpdate; }
+ if(idleTimeoutToUpdate != null) { idleTimeout = idleTimeoutToUpdate; }
+ if(hardTimeoutToUpdate != null) { hardTimeout = hardTimeoutToUpdate; }
if(dpidToUpdate != null) { dpid = dpidToUpdate; }
if(userStateToUpdate != null) { userState = userStateToUpdate; }
if(switchStateToUpdate != null) { switchState = switchStateToUpdate; }
@@ -844,6 +873,7 @@
public void clearUncommitedData() {
stateToUpdate = typeToUpdate = entryIdToUpdate = dpidToUpdate = null;
+ idleTimeoutToUpdate = hardTimeoutToUpdate = null;
userStateToUpdate = switchStateToUpdate = errorStateTypeToUpdate = errorStateCodeToUpdate = null;
matchInPortToUpdate = null;
matchSrcMacToUpdate = matchDstMacToUpdate = null;
@@ -864,6 +894,8 @@
public void setStateForTest(String state) { this.state = state; }
public void setTypeForTest(String type) { this.type = type; }
public void setEntryIdForTest(String entryId) { this.entryId = entryId; }
+ public void setIdleTimeoutForTest(Integer idleTimeout) { this.idleTimeout = idleTimeout; }
+ public void setHardTimeoutForTest(Integer hardTimeout) { this.hardTimeout = hardTimeout; }
public void setDpidForTest(String dpid) { this.dpid = dpid; }
public void setUserStateForTest(String userState) { this.userState = userState; }
public void setSwitchStateForTest(String switchState) { this.switchState = switchState; }
@@ -911,6 +943,18 @@
@Override
public void setFlowEntryId(String flowEntryId) { entryIdToUpdate = flowEntryId; }
+
+ @Override
+ public Integer getIdleTimeout() { return idleTimeout; }
+
+ @Override
+ public void setIdleTimeout(Integer idleTimeout) { idleTimeoutToUpdate = idleTimeout; }
+
+ @Override
+ public Integer getHardTimeout() { return hardTimeout; }
+
+ @Override
+ public void setHardTimeout(Integer hardTimeout) { hardTimeoutToUpdate = hardTimeout; }
@Override
public String getSwitchDpid() { return dpid; }
diff --git a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
index c7c74a5..9964ec3 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
@@ -2,6 +2,8 @@
import static org.junit.Assert.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
@@ -485,9 +487,10 @@
IDeviceObject dev1 = ope.searchDevice(macAddr);
assertEquals(macAddr, dev1.getMACAddress());
+ int ip_int = getPackedIPv4Address(ip);
//XXX not updated to new interface
- //IDeviceObject dev = deviceImpl.getDeviceByIP(ip);
- IDeviceObject dev = null;
+ IDeviceObject dev = deviceImpl.getDeviceByIP(ip_int);
+ //IDeviceObject dev = null;
assertNotNull(dev);
@@ -656,4 +659,14 @@
}
}
+ int getPackedIPv4Address(String ip) throws UnknownHostException {
+ byte[] bytes = InetAddress.getByName(ip).getAddress();
+
+ int val = 0;
+ for (int i = 0; i < bytes.length; i++) {
+ val <<= 8;
+ val |= bytes[i] & 0xff;
+ }
+ return val;
+ }
}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
index c54e89d..b43ce1c 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
@@ -26,7 +26,6 @@
import net.onrc.onos.ofcontroller.util.*;
import org.easymock.EasyMock;
-import org.easymock.IAnswer;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
@@ -124,6 +123,7 @@
return flowPath;
}
+ /*
private ArrayList<FlowPath> createTestFlowPaths() {
FlowPath flowPath1 = createTestFlowPath(1, "foo caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2);
FlowPath flowPath2 = createTestFlowPath(2, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2);
@@ -136,6 +136,7 @@
return flowPaths;
}
+ */
// IFlowService methods
@@ -710,7 +711,7 @@
fm.init(context);
// Use reflection to test the private method
// Boolean result = fm.reconcileFlow(iFlowPath1, dataPath);
- Class fmClass = FlowManager.class;
+ Class<?> fmClass = FlowManager.class;
Method method = fmClass.getDeclaredMethod(
"reconcileFlow",
new Class[] { IFlowPath.class, DataPath.class });
@@ -772,7 +773,7 @@
fm.init(context);
// Use reflection to test the private method
// Boolean result = fm.installFlowEntry(iofSwitch, iFlowPath, iFlowEntry);
- Class fmClass = FlowManager.class;
+ Class<?> fmClass = FlowManager.class;
Method method = fmClass.getDeclaredMethod(
"installFlowEntry",
new Class[] { IOFSwitch.class, IFlowPath.class, IFlowEntry.class });
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java
index 5b1bbdd..68b4f1f 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java
@@ -6,13 +6,14 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
-import io.netty.util.concurrent.Future;
import net.floodlightcontroller.core.IOFSwitch;
import net.onrc.onos.graph.GraphDBOperation;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.flowmanager.FlowDatabaseOperation;
+import net.onrc.onos.ofcontroller.flowprogrammer.IFlowSyncService.SyncResult;
import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryId;
@@ -91,7 +92,7 @@
initMockGraph(new long[] {1});
// synchronize
- doSynchronization(sw,100);
+ doSynchronization(sw);
// check if flow is not changed
assertEquals(0, idAdded.size());
@@ -110,7 +111,7 @@
initMockGraph(new long[] {1});
// synchronize
- doSynchronization(sw,100);
+ doSynchronization(sw);
// check if single flow is installed
assertEquals(1, idAdded.size());
@@ -130,7 +131,7 @@
initMockGraph(new long[] {});
// synchronize
- doSynchronization(sw,100);
+ doSynchronization(sw);
// check if single flow is deleted
assertEquals(0, idAdded.size());
@@ -151,7 +152,7 @@
initMockGraph(new long[] {2,3,4,5});
// synchronize
- doSynchronization(sw,100);
+ doSynchronization(sw);
// check if two flows {4,5} is installed and one flow {1} is deleted
assertEquals(2, idAdded.size());
@@ -179,7 +180,7 @@
initMockGraph(dbIdList);
// synchronize
- doSynchronization(sw, 3000);
+ doSynchronization(sw);
// check if 1500 flows {2000-3499} is installed and 1500 flows {0,...,1499} is deleted
assertEquals(1500, idAdded.size());
@@ -299,15 +300,14 @@
* Instantiate FlowSynchronizer and sync flows.
* @param sw Target IOFSwitch object
*/
- private void doSynchronization(IOFSwitch sw, long wait) {
+ private void doSynchronization(IOFSwitch sw) {
sync = new FlowSynchronizer();
sync.init(pusher);
- sync.synchronize(sw);
-
+ Future<SyncResult> future = sync.synchronize(sw);
try {
- Thread.sleep(wait);
- } catch (InterruptedException e) {
- fail("Failed to sleep");
+ future.get();
+ } catch (Exception e) {
+ fail("Failed to Future#get()");
}
}
}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
index 09d0a00..e054e05 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
@@ -2,7 +2,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import java.util.Map;
import org.easymock.EasyMock;
diff --git a/src/test/java/net/onrc/onos/ofcontroller/util/FlowEntryTest.java b/src/test/java/net/onrc/onos/ofcontroller/util/FlowEntryTest.java
index fc17178..696f9e5 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/util/FlowEntryTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/util/FlowEntryTest.java
@@ -13,6 +13,8 @@
FlowId flowId = new FlowId(0x1234);
FlowEntryId flowEntryId = new FlowEntryId(0x5678);
+ int idleTimeout = 5;
+ int hardTimeout = 10;
FlowEntryMatch match;
FlowEntryActions actions;
@@ -50,6 +52,9 @@
flowEntryId = new FlowEntryId("0x5678");
entry.setFlowEntryId(flowEntryId);
+
+ entry.setIdleTimeout(5);
+ entry.setHardTimeout(10);
dpid = new Dpid("CA:FE");
entry.setDpid( dpid );
@@ -188,6 +193,16 @@
}
@Test
+ public void testIdleTimeout(){
+ assertEquals("idleTimeout", idleTimeout, entry.idleTimeout() );
+ }
+
+ @Test
+ public void testHardTimeout(){
+ assertEquals("hardTimeout", hardTimeout, entry.hardTimeout() );
+ }
+
+ @Test
public void testFlowEntryMatch(){
assertEquals("flowEntryMatch", match, entry.flowEntryMatch() );
}
@@ -237,8 +252,8 @@
@Test
public void testToString(){
FlowEntry def = new FlowEntry();
- assertEquals("toString", def.toString(), "[ flowEntryActions=[] flowEntryUserState=FE_USER_UNKNOWN flowEntrySwitchState=FE_SWITCH_UNKNOWN]" );
- assertEquals("toString", entry.toString(), "[flowEntryId=0x5678 flowId=0x1234 flowEntryMatch=[inPort=1 srcMac=01:02:03:04:05:06 dstMac=06:05:04:03:02:01 ethernetFrameType=2 vlanId=3 vlanPriority=4 srcIPv4Net=127.0.0.1/32 dstIPv4Net=127.0.0.2/32 ipProto=5 ipToS=6 srcTcpUdpPort=7 dstTcpUdpPort=8] flowEntryActions=[[type=ACTION_OUTPUT action=[port=9 maxLen=0]];[type=ACTION_OUTPUT action=[port=-3 maxLen=0]];[type=ACTION_SET_VLAN_VID action=[vlanId=3]];[type=ACTION_SET_VLAN_PCP action=[vlanPriority=4]];[type=ACTION_STRIP_VLAN action=[stripVlan=true]];[type=ACTION_SET_DL_SRC action=[addr=01:02:03:04:05:06]];[type=ACTION_SET_DL_DST action=[addr=06:05:04:03:02:01]];[type=ACTION_SET_NW_SRC action=[addr=127.0.0.3]];[type=ACTION_SET_NW_DST action=[addr=127.0.0.4]];[type=ACTION_SET_NW_TOS action=[ipToS=6]];[type=ACTION_SET_TP_SRC action=[port=7]];[type=ACTION_SET_TP_DST action=[port=8]];[type=ACTION_ENQUEUE action=[port=10 queueId=11]];] dpid=00:00:00:00:00:00:ca:fe inPort=1 outPort=9 flowEntryUserState=FE_USER_ADD flowEntrySwitchState=FE_SWITCH_UPDATED flowEntryErrorState=[type=12 code=13]]" );
+ assertEquals("toString", def.toString(), "[ idleTimeout=0 hardTimeout=0 flowEntryActions=[] flowEntryUserState=FE_USER_UNKNOWN flowEntrySwitchState=FE_SWITCH_UNKNOWN]" );
+ assertEquals("toString", entry.toString(), "[flowEntryId=0x5678 flowId=0x1234 idleTimeout=5 hardTimeout=10 flowEntryMatch=[inPort=1 srcMac=01:02:03:04:05:06 dstMac=06:05:04:03:02:01 ethernetFrameType=2 vlanId=3 vlanPriority=4 srcIPv4Net=127.0.0.1/32 dstIPv4Net=127.0.0.2/32 ipProto=5 ipToS=6 srcTcpUdpPort=7 dstTcpUdpPort=8] flowEntryActions=[[type=ACTION_OUTPUT action=[port=9 maxLen=0]];[type=ACTION_OUTPUT action=[port=-3 maxLen=0]];[type=ACTION_SET_VLAN_VID action=[vlanId=3]];[type=ACTION_SET_VLAN_PCP action=[vlanPriority=4]];[type=ACTION_STRIP_VLAN action=[stripVlan=true]];[type=ACTION_SET_DL_SRC action=[addr=01:02:03:04:05:06]];[type=ACTION_SET_DL_DST action=[addr=06:05:04:03:02:01]];[type=ACTION_SET_NW_SRC action=[addr=127.0.0.3]];[type=ACTION_SET_NW_DST action=[addr=127.0.0.4]];[type=ACTION_SET_NW_TOS action=[ipToS=6]];[type=ACTION_SET_TP_SRC action=[port=7]];[type=ACTION_SET_TP_DST action=[port=8]];[type=ACTION_ENQUEUE action=[port=10 queueId=11]];] dpid=00:00:00:00:00:00:ca:fe inPort=1 outPort=9 flowEntryUserState=FE_USER_ADD flowEntrySwitchState=FE_SWITCH_UPDATED flowEntryErrorState=[type=12 code=13]]" );
}
}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java b/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java
index bd42ac8..76ccf9f 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java
@@ -19,6 +19,8 @@
iFlowPath.setFlowPathTypeForTest("FP_TYPE_SHORTEST_PATH");
iFlowPath.setFlowPathUserStateForTest("FP_USER_ADD");
iFlowPath.setFlowPathFlagsForTest(0L);
+ iFlowPath.setIdleTimeoutForTest(5);
+ iFlowPath.setHardTimeoutForTest(10);
iFlowPath.setSrcSwForTest("CA:FE");
iFlowPath.setSrcPortForTest((short)1);
iFlowPath.setDstSwForTest("BA:BE");
@@ -44,6 +46,8 @@
assertTrue ( flowPath.flowPathUserState() == FlowPathUserState.FP_USER_UNKNOWN);
assertFalse( flowPath.flowPathFlags().isDiscardFirstHopEntry() );
assertFalse( flowPath.flowPathFlags().isKeepOnlyFirstHopEntry() );
+ assertTrue (flowPath.idleTimeout() == 0);
+ assertTrue (flowPath.hardTimeout() == 0);
assertTrue( flowPath.flowEntryActions().isEmpty() );
}
@@ -55,6 +59,8 @@
iFlowPath.setFlowPathTypeForTest("FP_TYPE_SHORTEST_PATH");
iFlowPath.setFlowPathUserStateForTest("FP_USER_ADD");
iFlowPath.setFlowPathFlagsForTest(0L);
+ iFlowPath.setIdleTimeoutForTest(5);
+ iFlowPath.setHardTimeoutForTest(10);
iFlowPath.setSrcSwForTest("CA:FE");
iFlowPath.setSrcPortForTest((short)1);
iFlowPath.setDstSwForTest("BA:BE");
@@ -100,6 +106,8 @@
assertEquals(flowPath.flowPathType(), FlowPathType.FP_TYPE_SHORTEST_PATH);
assertEquals(flowPath.flowPathUserState(), FlowPathUserState.FP_USER_ADD);
assertEquals(flowPath.flowPathFlags().flags(), 0);
+ assertEquals(flowPath.idleTimeout(), 5);
+ assertEquals(flowPath.hardTimeout(), 10);
assertEquals(flowPath.dataPath().srcPort().dpid().value(), 0xCAFE);
assertEquals(flowPath.dataPath().srcPort().port().value(), 1);
assertEquals(flowPath.dataPath().dstPort().dpid().value(), 0xBABE);
@@ -123,6 +131,8 @@
assertEquals(0x14, flowPath.dataPath().flowEntries().get(0).flowEntryId().value() );
assertEquals(0xBEEF, flowPath.dataPath().flowEntries().get(0).dpid().value() );
+ assertEquals(0, flowPath.dataPath().flowEntries().get(0).idleTimeout() );
+ assertEquals(0, flowPath.dataPath().flowEntries().get(0).hardTimeout() );
assertEquals(15, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().inPort().value() );
assertEquals("11:22:33:44:55:66", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcMac().toString());
assertEquals("66:55:44:33:22:11", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstMac().toString());
@@ -179,6 +189,22 @@
}
@Test
+ public void testSetIdleTimeout(){
+ FlowPath flowPath = new FlowPath();
+ int idleTimeout = 15;
+ flowPath.setIdleTimeout( idleTimeout );
+ assertTrue( flowPath.idleTimeout() == 15 );
+ }
+
+ @Test
+ public void testSetHardTimeout(){
+ FlowPath flowPath = new FlowPath();
+ int hardTimeout = 20;
+ flowPath.setHardTimeout( hardTimeout );
+ assertTrue( flowPath.hardTimeout() == 20 );
+ }
+
+ @Test
public void testSetDataPath(){
FlowPath flowPath = new FlowPath();
DataPath dataPath = new DataPath();
@@ -189,7 +215,7 @@
@Test
public void testToString(){
- assertEquals("[flowId=0x1234 installerId=installerId flowPathType=FP_TYPE_SHORTEST_PATH flowPathUserState=FP_USER_ADD flowPathFlags=[flags=] dataPath=[src=00:00:00:00:00:00:ca:fe/1 flowEntry=[flowEntryId=0x14 flowEntryMatch=[] flowEntryActions=[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];] dpid=00:00:00:00:00:00:be:ef flowEntryUserState=FE_USER_MODIFY flowEntrySwitchState=FE_SWITCH_UPDATE_IN_PROGRESS] dst=00:00:00:00:00:00:ba:be/2] flowEntryMatch=[] flowEntryActions=[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]]", flowPath.toString());
+ assertEquals("[flowId=0x1234 installerId=installerId flowPathType=FP_TYPE_SHORTEST_PATH flowPathUserState=FP_USER_ADD flowPathFlags=[flags=] idleTimeout=5 hardTimeout=10 dataPath=[src=00:00:00:00:00:00:ca:fe/1 flowEntry=[flowEntryId=0x14 idleTimeout=0 hardTimeout=0 flowEntryMatch=[] flowEntryActions=[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];] dpid=00:00:00:00:00:00:be:ef flowEntryUserState=FE_USER_MODIFY flowEntrySwitchState=FE_SWITCH_UPDATE_IN_PROGRESS] dst=00:00:00:00:00:00:ba:be/2] flowEntryMatch=[] flowEntryActions=[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]]", flowPath.toString());
}
@Test
diff --git a/start-onos-embedded.sh b/start-onos-embedded.sh
index 8688f69..6fc9362 100755
--- a/start-onos-embedded.sh
+++ b/start-onos-embedded.sh
@@ -17,7 +17,7 @@
#JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
-JVM_OPTS="$JVM_OPTS -javaagent:lib/jamm-0.2.5.jar"
+JVM_OPTS="$JVM_OPTS -javaagent:$ONOS_HOME/lib/jamm-0.2.5.jar"
JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8 \
-XX:+UseThreadPriorities \
-XX:ThreadPriorityPolicy=42 \
@@ -90,7 +90,7 @@
</configuration>
EOF_LOGBACK
- # Run floodlight
+ # Run ONOS
echo "Starting ONOS controller ..."
echo
diff --git a/start-onos-jacoco.sh b/start-onos-jacoco.sh
new file mode 100755
index 0000000..2e04216
--- /dev/null
+++ b/start-onos-jacoco.sh
@@ -0,0 +1,184 @@
+#!/bin/bash
+
+# Set paths
+if [ -z "${ONOS_HOME}" ]; then
+ ONOS_HOME=`dirname $0`
+fi
+
+## Because the script change dir to $ONOS_HOME, we can set ONOS_LOGBACK and LOGDIR relative to $ONOS_HOME
+#ONOS_LOGBACK="${ONOS_HOME}/logback.`hostname`.xml"
+#LOGDIR=${ONOS_HOME}/onos-logs
+ONOS_LOGBACK="./logback.`hostname`.xml"
+LOGDIR=./onos-logs
+ONOS_LOG="${LOGDIR}/onos.`hostname`.log"
+PCAP_LOG="${LOGDIR}/onos.`hostname`.pcap"
+LOGS="$ONOS_LOG $PCAP_LOG"
+
+# Set JVM options
+JVM_OPTS=""
+## If you want JaCoCo Code Coverage reports... uncomment line below
+JVM_OPTS="$JVM_OPTS -javaagent:${ONOS_HOME}/lib/jacocoagent.jar=dumponexit=true,output=file,destfile=${LOGDIR}/jacoco.exec"
+JVM_OPTS="$JVM_OPTS -server -d64"
+#JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
+JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
+#JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
+JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8"
+JVM_OPTS="$JVM_OPTS -XX:OnError=crash-logger" ;# For dumping core
+#JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
+JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8 \
+ -XX:+UseThreadPriorities \
+ -XX:ThreadPriorityPolicy=42 \
+ -XX:+UseCompressedOops \
+ -Dcom.sun.management.jmxremote.port=7189 \
+ -Dcom.sun.management.jmxremote.ssl=false \
+ -Dcom.sun.management.jmxremote.authenticate=false"
+JVM_OPTS="$JVM_OPTS -Dhazelcast.logging.type=slf4j"
+
+# Set ONOS core main class
+MAIN_CLASS="net.onrc.onos.ofcontroller.core.Main"
+
+if [ -z "${MVN}" ]; then
+ MVN="mvn -o"
+fi
+
+#<logger name="net.floodlightcontroller.linkdiscovery.internal" level="TRACE"/>
+#<appender-ref ref="STDOUT" />
+
+function lotate {
+ logfile=$1
+ nr_max=${2:-10}
+ if [ -f $logfile ]; then
+ for i in `seq $(expr $nr_max - 1) -1 1`; do
+ if [ -f ${logfile}.${i} ]; then
+ mv -f ${logfile}.${i} ${logfile}.`expr $i + 1`
+ fi
+ done
+ mv $logfile $logfile.1
+ fi
+}
+
+function start {
+ if [ ! -d ${LOGDIR} ]; then
+ mkdir -p ${LOGDIR}
+ fi
+ # Backup log files
+ for log in ${LOGS}; do
+ echo "rotate log: $log"
+ if [ -f ${log} ]; then
+ lotate ${log}
+ fi
+ done
+
+# Create a logback file if required
+ if [ ! -f ${ONOS_LOGBACK} ]; then
+ cat <<EOF_LOGBACK >${ONOS_LOGBACK}
+<configuration scan="true" debug="true">
+<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+<encoder>
+<pattern>%level [%logger:%thread] %msg%n</pattern>
+</encoder>
+</appender>
+
+<appender name="FILE" class="ch.qos.logback.core.FileAppender">
+<file>${ONOS_LOG}</file>
+<encoder>
+<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
+</encoder>
+</appender>
+
+<logger name="org" level="WARN"/>
+<logger name="LogService" level="WARN"/> <!-- Restlet access logging -->
+<logger name="net.floodlightcontroller.logging" level="WARN"/>
+
+<root level="DEBUG">
+<appender-ref ref="FILE" />
+</root>
+</configuration>
+EOF_LOGBACK
+ fi
+
+ # Run ONOS
+ echo "Starting ONOS controller ..."
+ echo
+
+ # XXX : MVN has to run at the project top dir
+ echo $ONOS_HOME
+ cd ${ONOS_HOME}
+ pwd
+ echo "${MVN} exec:exec -Dexec.executable=\"java\" -Dexec.args=\"${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ./conf/onos.properties\""
+
+ ${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ./conf/onos.properties" > ${LOGDIR}/onos.`hostname`.stdout 2>${LOGDIR}/onos.`hostname`.stderr &
+
+ echo "Waiting for ONOS to start..."
+ COUNT=0
+ ESTATE=0
+ while [ "$COUNT" != "10" ]; do
+ echo -n "."
+ sleep 1
+# COUNT=$((COUNT + 1))
+# sleep $COUNT
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
+ if [ "$n" -ge "1" ]; then
+ echo ""
+ exit 0
+ fi
+ done
+ echo "Timed out"
+ exit 1
+
+# echo "java ${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -jar ${ONOS_JAR} -cf ./onos.properties > /dev/null 2>&1 &"
+# sudo -b /usr/sbin/tcpdump -n -i eth0 -s0 -w ${PCAP_LOG} 'tcp port 6633' > /dev/null 2>&1
+}
+
+function stop {
+ # Kill the existing processes
+ flpid=`jps -l |grep ${MAIN_CLASS} | awk '{print $1}'`
+ tdpid=`ps -edalf |grep tcpdump |grep ${PCAP_LOG} | awk '{print $4}'`
+ pids="$flpid $tdpid"
+ for p in ${pids}; do
+ if [ x$p != "x" ]; then
+ kill -TERM $p
+ echo "Killed existing process (pid: $p)"
+ fi
+ done
+}
+
+function check_db {
+ if [ -d "/tmp/cassandra.titan" ]; then
+ echo "Cassandra is running on local berkely db. Exitting"
+ exit
+ fi
+ n=`ps -edalf |grep java |grep apache-cassandra | wc -l`
+ if [ x$n == "x0" ]; then
+ echo "Cassandra is not running. Exitting"
+ exit
+ fi
+}
+
+case "$1" in
+ start)
+ stop
+ check_db
+ start
+ ;;
+ startifdown)
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
+ if [ $n == 0 ]; then
+ start
+ else
+ echo "$n instance of onos running"
+ fi
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
+ echo "$n instance of onos running"
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart|status|startifdown}"
+ exit 1
+esac
diff --git a/start-onos.sh b/start-onos.sh
index 495141d..29a108c 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -17,7 +17,7 @@
# Set JVM options
JVM_OPTS=""
## If you want JaCoCo Code Coverage reports... uncomment line below
-JVM_OPTS="$JVM_OPTS -javaagent:${ONOS_HOME}/lib/jacocoagent.jar=dumponexit=true,output=file,destfile=${LOGDIR}/jacoco.exec"
+#JVM_OPTS="$JVM_OPTS -javaagent:${ONOS_HOME}/lib/jacocoagent.jar=dumponexit=true,output=file,destfile=${LOGDIR}/jacoco.exec"
JVM_OPTS="$JVM_OPTS -server -d64"
#JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
@@ -99,7 +99,7 @@
EOF_LOGBACK
fi
- # Run floodlight
+ # Run ONOS
echo "Starting ONOS controller ..."
echo
diff --git a/web/add_flow.py b/web/add_flow.py
index c621c30..9690024 100755
--- a/web/add_flow.py
+++ b/web/add_flow.py
@@ -129,9 +129,12 @@
my_dst_port = my_args[5]
#
- # Extract the "flowPathFlags", "match" and "action" arguments
+ # Extract the "flowPathFlags", "idleTimeout", "hardTimeout",
+ # "match" and "action" arguments.
#
flowPathFlags = 0L
+ idleTimeout = 0
+ hardTimeout = 0
match = {}
matchInPortEnabled = True # NOTE: Enabled by default
actions = []
@@ -155,6 +158,10 @@
flowPathFlags = flowPathFlags + 0x1
if "KEEP_ONLY_FIRST_HOP_ENTRY" in arg2:
flowPathFlags = flowPathFlags + 0x2
+ elif arg1 == "idleTimeout":
+ idleTimeout = arg2
+ elif arg1 == "hardTimeout":
+ hardTimeout = arg2
elif arg1 == "matchInPort":
# Just mark whether inPort matching is enabled
matchInPortEnabled = arg2 in ['True', 'true']
@@ -310,6 +317,8 @@
'my_dst_dpid' : my_dst_dpid,
'my_dst_port' : my_dst_port,
'flowPathFlags' : flowPathFlags,
+ 'idleTimeout' : idleTimeout,
+ 'hardTimeout' : hardTimeout,
'match' : match,
'matchInPortEnabled' : matchInPortEnabled,
'actions' : actions,
@@ -334,6 +343,8 @@
my_flow_id = parsed_args['my_flow_id']
my_installer_id = parsed_args['my_installer_id']
myFlowPathFlags = parsed_args['flowPathFlags']
+ myIdleTimeout = parsed_args['idleTimeout']
+ myHardTimeout = parsed_args['hardTimeout']
match = parsed_args['match']
matchInPortEnabled = parsed_args['matchInPortEnabled']
actions = parsed_args['actions']
@@ -356,6 +367,8 @@
flow_path['flowPathType'] = 'FP_TYPE_EXPLICIT_PATH'
flow_path['flowPathUserState'] = 'FP_USER_ADD'
flow_path['flowPathFlags'] = flowPathFlags
+ flow_path['idleTimeout'] = myIdleTimeout
+ flow_path['hardTimeout'] = myHardTimeout
if (len(match) > 0):
flow_path['flowEntryMatch'] = copy.deepcopy(match)
@@ -506,6 +519,10 @@
usage_msg = usage_msg + " DISCARD_FIRST_HOP_ENTRY : Discard the first-hop flow entry\n"
usage_msg = usage_msg + " KEEP_ONLY_FIRST_HOP_ENTRY : Keep only the first-hop flow entry\n"
usage_msg = usage_msg + "\n"
+ usage_msg = usage_msg + " Timeouts (in seconds in the [0, 65535] interval):\n"
+ usage_msg = usage_msg + " idleTimeout <idleTimeoutInSeconds> (default to 0: no timeout)\n"
+ usage_msg = usage_msg + " hardTimeout <hardTimeoutInSeconds> (default to 0: no timeout)\n"
+ usage_msg = usage_msg + "\n"
usage_msg = usage_msg + " Match Conditions:\n"
usage_msg = usage_msg + " matchInPort <True|False> (default to True)\n"
usage_msg = usage_msg + " matchSrcMac <source MAC address>\n"
@@ -516,7 +533,7 @@
usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
usage_msg = usage_msg + " matchIpProto <IP protocol>\n"
- usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
+ usage_msg = usage_msg + " matchIpToS <IP ToS> (DSCP field, 6 bits)\n"
usage_msg = usage_msg + " matchSrcTcpUdpPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " matchDstTcpUdpPort <destination TCP/UDP port>\n"
usage_msg = usage_msg + "\n"
@@ -529,7 +546,7 @@
usage_msg = usage_msg + " actionSetEthernetDstAddr <destination MAC address>\n"
usage_msg = usage_msg + " actionSetIPv4SrcAddr <source IPv4 address>\n"
usage_msg = usage_msg + " actionSetIPv4DstAddr <destination IPv4 address>\n"
- usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
+ usage_msg = usage_msg + " actionSetIpToS <IP ToS> (DSCP field, 6 bits)\n"
usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
usage_msg = usage_msg + " Actions (not implemented yet):\n"
diff --git a/web/get_flow.py b/web/get_flow.py
index 72fbd4a..94b9a61 100755
--- a/web/get_flow.py
+++ b/web/get_flow.py
@@ -164,6 +164,8 @@
flowPathType = parsedResult['flowPathType']
flowPathUserState = parsedResult['flowPathUserState']
flowPathFlags = parsedResult['flowPathFlags']['flags']
+ idleTimeout = parsedResult['idleTimeout']
+ hardTimeout = parsedResult['hardTimeout']
srcSwitch = parsedResult['dataPath']['srcPort']['dpid']['value']
srcPort = parsedResult['dataPath']['srcPort']['port']['value']
dstSwitch = parsedResult['dataPath']['dstPort']['dpid']['value']
@@ -181,7 +183,7 @@
flowPathFlagsStr += ","
flowPathFlagsStr += "KEEP_ONLY_FIRST_HOP_ENTRY"
- print "FlowPath: (flowId = %s installerId = %s flowPathType = %s flowPathUserState = %s flowPathFlags = 0x%x(%s) src = %s/%s dst = %s/%s)" % (flowId, installerId, flowPathType, flowPathUserState, flowPathFlags, flowPathFlagsStr, srcSwitch, srcPort, dstSwitch, dstPort)
+ print "FlowPath: (flowId = %s installerId = %s flowPathType = %s flowPathUserState = %s flowPathFlags = 0x%x(%s) src = %s/%s dst = %s/%s idleTimeout = %s hardTimeout = %s)" % (flowId, installerId, flowPathType, flowPathUserState, flowPathFlags, flowPathFlagsStr, srcSwitch, srcPort, dstSwitch, dstPort, idleTimeout, hardTimeout)
#
# Print the common match conditions
@@ -205,13 +207,15 @@
#
for f in parsedResult['dataPath']['flowEntries']:
flowEntryId = f['flowEntryId']
+ idleTimeout = f['idleTimeout']
+ hardTimeout = f['hardTimeout']
dpid = f['dpid']['value']
userState = f['flowEntryUserState']
switchState = f['flowEntrySwitchState']
match = f['flowEntryMatch'];
actions = f['flowEntryActions']['actions']
- print " FlowEntry: (%s, %s, %s, %s)" % (flowEntryId, dpid, userState, switchState)
+ print " FlowEntry: (%s, %s, %s, %s, idleTimeout = %s, hardTimeout = %s)" % (flowEntryId, dpid, userState, switchState, idleTimeout, hardTimeout)
#
# Print the match conditions