Merge pull request #3 from y-higuchi/RAMCloud-yoshi
merge latest
diff --git a/conf/checkstyle/sun_checks.xml b/conf/checkstyle/sun_checks.xml
new file mode 100644
index 0000000..51a7f8c
--- /dev/null
+++ b/conf/checkstyle/sun_checks.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+ "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+ "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+
+ Checkstyle configuration that checks the sun coding conventions from:
+
+ - the Java Language Specification at
+ http://java.sun.com/docs/books/jls/second_edition/html/index.html
+
+ - the Sun Code Conventions at http://java.sun.com/docs/codeconv/
+
+ - the Javadoc guidelines at
+ http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
+
+ - the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html
+
+ - some best practices
+
+ Checkstyle is very configurable. Be sure to read the documentation at
+ http://checkstyle.sf.net (or in your downloaded distribution).
+
+ Most Checks are configurable, be sure to consult the documentation.
+
+ To completely disable a check, just comment it out or delete it from the file.
+
+ Finally, it is worth reading the documentation.
+
+-->
+
+<module name="Checker">
+ <!--
+ If you set the basedir property below, then all reported file
+ names will be relative to the specified directory. See
+ http://checkstyle.sourceforge.net/5.x/config.html#Checker
+
+ <property name="basedir" value="${basedir}"/>
+ -->
+
+ <!-- Checks that a package-info.java file exists for each package. -->
+ <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage -->
+ <module name="JavadocPackage"/>
+
+ <!-- Checks whether files end with a new line. -->
+ <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
+ <module name="NewlineAtEndOfFile"/>
+
+ <!-- Checks that property files contain the same keys. -->
+ <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
+ <module name="Translation"/>
+
+ <!-- Checks for Size Violations. -->
+ <!-- See http://checkstyle.sf.net/config_sizes.html -->
+ <module name="FileLength"/>
+
+ <!-- Checks for whitespace -->
+ <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+ <module name="FileTabCharacter"/>
+
+ <!-- Miscellaneous other checks. -->
+ <!-- See http://checkstyle.sf.net/config_misc.html -->
+ <module name="RegexpSingleline">
+ <property name="format" value="\s+$"/>
+ <property name="minimum" value="0"/>
+ <property name="maximum" value="0"/>
+ <property name="message" value="Line has trailing spaces."/>
+ </module>
+
+ <!-- Checks for Headers -->
+ <!-- See http://checkstyle.sf.net/config_header.html -->
+ <!-- <module name="Header"> -->
+ <!-- <property name="headerFile" value="${checkstyle.header.file}"/> -->
+ <!-- <property name="fileExtensions" value="java"/> -->
+ <!-- </module> -->
+
+ <module name="TreeWalker">
+
+ <!-- Checks for Javadoc comments. -->
+ <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+ <module name="JavadocMethod"/>
+ <module name="JavadocType"/>
+ <module name="JavadocVariable"/>
+ <module name="JavadocStyle"/>
+
+
+ <!-- Checks for Naming Conventions. -->
+ <!-- See http://checkstyle.sf.net/config_naming.html -->
+ <module name="ConstantName"/>
+ <module name="LocalFinalVariableName"/>
+ <module name="LocalVariableName"/>
+ <module name="MemberName"/>
+ <module name="MethodName"/>
+ <module name="PackageName"/>
+ <module name="ParameterName"/>
+ <module name="StaticVariableName"/>
+ <module name="TypeName"/>
+
+
+ <!-- Checks for imports -->
+ <!-- See http://checkstyle.sf.net/config_import.html -->
+ <module name="AvoidStarImport"/>
+ <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+ <module name="RedundantImport"/>
+ <module name="UnusedImports"/>
+
+
+ <!-- Checks for Size Violations. -->
+ <!-- See http://checkstyle.sf.net/config_sizes.html -->
+ <module name="LineLength"/>
+ <module name="MethodLength"/>
+ <module name="ParameterNumber"/>
+
+
+ <!-- Checks for whitespace -->
+ <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+ <module name="EmptyForIteratorPad"/>
+ <module name="GenericWhitespace"/>
+ <module name="MethodParamPad"/>
+ <module name="NoWhitespaceAfter"/>
+ <module name="NoWhitespaceBefore"/>
+ <module name="OperatorWrap"/>
+ <module name="ParenPad"/>
+ <module name="TypecastParenPad"/>
+ <module name="WhitespaceAfter"/>
+ <module name="WhitespaceAround"/>
+
+
+ <!-- Modifier Checks -->
+ <!-- See http://checkstyle.sf.net/config_modifiers.html -->
+ <module name="ModifierOrder"/>
+ <module name="RedundantModifier"/>
+
+
+ <!-- Checks for blocks. You know, those {}'s -->
+ <!-- See http://checkstyle.sf.net/config_blocks.html -->
+ <module name="AvoidNestedBlocks"/>
+ <module name="EmptyBlock"/>
+ <module name="LeftCurly"/>
+ <module name="NeedBraces"/>
+ <module name="RightCurly"/>
+
+
+ <!-- Checks for common coding problems -->
+ <!-- See http://checkstyle.sf.net/config_coding.html -->
+ <module name="AvoidInlineConditionals"/>
+ <module name="EmptyStatement"/>
+ <module name="EqualsHashCode"/>
+ <module name="HiddenField"/>
+ <module name="IllegalInstantiation"/>
+ <module name="InnerAssignment"/>
+ <module name="MagicNumber"/>
+ <module name="MissingSwitchDefault"/>
+ <module name="RedundantThrows"/>
+ <module name="SimplifyBooleanExpression"/>
+ <module name="SimplifyBooleanReturn"/>
+
+ <!-- Checks for class design -->
+ <!-- See http://checkstyle.sf.net/config_design.html -->
+ <module name="DesignForExtension"/>
+ <module name="FinalClass"/>
+ <module name="HideUtilityClassConstructor"/>
+ <module name="InterfaceIsType"/>
+ <module name="VisibilityModifier"/>
+
+
+ <!-- Miscellaneous other checks. -->
+ <!-- See http://checkstyle.sf.net/config_misc.html -->
+ <module name="ArrayTypeStyle"/>
+ <module name="FinalParameters"/>
+ <module name="TodoComment"/>
+ <module name="UpperEll"/>
+
+ </module>
+
+</module>
diff --git a/conf/onos-embedded.properties b/conf/onos-embedded.properties
index 8ae143e..dddacdb 100644
--- a/conf/onos-embedded.properties
+++ b/conf/onos-embedded.properties
@@ -1,7 +1,6 @@
floodlight.modules = net.floodlightcontroller.core.FloodlightProvider,\
net.floodlightcontroller.threadpool.ThreadPool,\
net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
-net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
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 ec04622..f1244df 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -1,7 +1,6 @@
floodlight.modules = net.floodlightcontroller.core.FloodlightProvider,\
net.floodlightcontroller.threadpool.ThreadPool,\
net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
-net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
net.floodlightcontroller.ui.web.StaticWebRoutable,\
net.onrc.onos.datagrid.HazelcastDatagrid,\
net.onrc.onos.ofcontroller.flowmanager.FlowManager,\
diff --git a/perf-scripts/flow-sync-perf.py b/perf-scripts/flow-sync-perf.py
index f0af050..b782333 100755
--- a/perf-scripts/flow-sync-perf.py
+++ b/perf-scripts/flow-sync-perf.py
@@ -203,7 +203,7 @@
setLogLevel( 'output' )
resultDir = strftime( '%Y%m%d-%H%M%S' )
os.mkdir( resultDir )
- tests = sys.argv[1:]
+ tests = map(int, sys.argv[1:])
if not tests:
tests = [1, 10, 100, 1000, 10000]
runPerf( resultDir, tests )
diff --git a/pom.xml b/pom.xml
index af6c709..87816b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,11 +32,20 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<powermock.version>1.5.1</powermock.version>
<restlet.version>2.1.4</restlet.version>
- <github.global.server>github</github.global.server>
+ <!-- <github.global.server>github</github.global.server> -->
</properties>
<build>
<plugins>
<plugin>
+ <!-- Note: the checkstyle configuration is also in the reporting section -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>2.11</version>
+ <configuration>
+ <configLocation>conf/checkstyle/sun_checks.xml</configLocation>
+ </configuration>
+ </plugin>
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
@@ -145,6 +154,7 @@
</execution>
</executions>
</plugin>
+ <!--
<plugin>
<groupId>com.github.github</groupId>
<artifactId>site-maven-plugin</artifactId>
@@ -164,6 +174,7 @@
</execution>
</executions>
</plugin>
+ -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
@@ -213,6 +224,27 @@
<locale>en</locale>
</configuration>
</plugin>
+ <plugin>
+ <!-- Note: the checkstyle configuration is also in the build section -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>2.11</version>
+ <configuration>
+ <configLocation>conf/checkstyle/sun_checks.xml</configLocation>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>checkstyle</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
</plugins>
</reporting>
<dependencies>
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 39bdf3c..42fb3c6 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -61,6 +61,7 @@
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.core.web.OnosInternalWebRoutable;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.registry.controller.IControllerRegistryService;
import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
@@ -1831,6 +1832,7 @@
// Add our REST API
restApi.addRestletRoutable(new CoreWebRoutable());
+ restApi.addRestletRoutable(new OnosInternalWebRoutable());
}
@Override
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index 9b22617..0e48975 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -19,10 +19,6 @@
import net.floodlightcontroller.core.module.ModuleLoaderResource;
import net.floodlightcontroller.restserver.RestletRoutable;
-import net.onrc.onos.ofcontroller.core.web.ClearFlowTableResource;
-import net.onrc.onos.ofcontroller.core.web.TopoLinksResource;
-import net.onrc.onos.ofcontroller.core.web.TopoSwitchesResource;
-import net.onrc.onos.ofcontroller.devicemanager.web.TopoDevicesResource;
import org.restlet.Context;
import org.restlet.Restlet;
@@ -35,7 +31,7 @@
public class CoreWebRoutable implements RestletRoutable {
@Override
public String basePath() {
- return "/wm/core";
+ return "/wm/floodlight/core";
}
@Override
@@ -57,11 +53,6 @@
EventHistoryTopologyClusterResource.class);
router.attach("/health/json", HealthCheckResource.class);
router.attach("/system/uptime/json", SystemUptimeResource.class);
- // Following added by ONOS
- router.attach("/topology/switches/{filter}/json", TopoSwitchesResource.class);
- router.attach("/topology/links/json", TopoLinksResource.class);
- router.attach("/topology/devices/json", TopoDevicesResource.class);
- router.attach("/clearflowtable/json", ClearFlowTableResource.class);
return router;
}
}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceRoutable.java b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceRoutable.java
index 9a76505..3648569 100644
--- a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceRoutable.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceRoutable.java
@@ -30,7 +30,7 @@
@Override
public String basePath() {
- return "/wm/device";
+ return "/wm/floodlight/device";
}
@Override
diff --git a/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java b/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
index 4f844b2..363a194 100644
--- a/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
@@ -4,8 +4,6 @@
import org.restlet.routing.Router;
import net.floodlightcontroller.restserver.RestletRoutable;
-import net.onrc.onos.ofcontroller.linkdiscovery.web.LinksResource;
-import net.onrc.onos.ofcontroller.topology.web.RouteResource;
public class TopologyWebRoutable implements RestletRoutable {
/**
@@ -14,13 +12,11 @@
@Override
public Router getRestlet(Context context) {
Router router = new Router(context);
- router.attach("/links/json", LinksResource.class);
router.attach("/tunnellinks/json", TunnelLinksResource.class);
router.attach("/switchclusters/json", SwitchClustersResource.class);
router.attach("/broadcastdomainports/json", BroadcastDomainPortsResource.class);
router.attach("/enabledports/json", EnabledPortsResource.class);
router.attach("/blockedports/json", BlockedPortsResource.class);
- router.attach("/route/{src-dpid}/{src-port}/{dst-dpid}/{dst-port}/json", RouteResource.class);
return router;
}
@@ -29,6 +25,6 @@
*/
@Override
public String basePath() {
- return "/wm/topology";
+ return "/wm/floodlight/topology";
}
}
diff --git a/src/main/java/net/floodlightcontroller/ui/web/StaticWebRoutable.java b/src/main/java/net/floodlightcontroller/ui/web/StaticWebRoutable.java
index c1d5b5f..e89f0be 100644
--- a/src/main/java/net/floodlightcontroller/ui/web/StaticWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/ui/web/StaticWebRoutable.java
@@ -64,7 +64,7 @@
@Override
public String basePath() {
- return "/ui/";
+ return "/wm/floodlight/ui/";
}
}
diff --git a/src/main/java/net/floodlightcontroller/util/MACAddress.java b/src/main/java/net/floodlightcontroller/util/MACAddress.java
index b143bda..fc144bb 100644
--- a/src/main/java/net/floodlightcontroller/util/MACAddress.java
+++ b/src/main/java/net/floodlightcontroller/util/MACAddress.java
@@ -8,6 +8,7 @@
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.openflow.util.HexString;
/**
* The class representing MAC address.
@@ -167,13 +168,6 @@
@Override
public String toString() {
- StringBuilder builder = new StringBuilder();
- for (byte b: address) {
- if (builder.length() > 0) {
- builder.append(":");
- }
- builder.append(String.format("%02X", b & 0xFF));
- }
- return builder.toString();
+ return HexString.toHexString(address);
}
}
diff --git a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
index 2c99ece..1d3afe7 100644
--- a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
@@ -25,6 +25,6 @@
*/
@Override
public String basePath() {
- return "/wm/datagrid";
+ return "/wm/onos/datagrid";
}
}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
index 0b5c9c6..ab775b9 100644
--- a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
+++ b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
@@ -44,8 +44,9 @@
* Create a new switch and return the created switch object.
* @param dpid DPID of the switch
*/
+ @Override
public ISwitchObject newSwitch(String dpid) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
ISwitchObject obj = fg.addVertex(null,ISwitchObject.class);
if (obj != null) {
obj.setType("switch");
@@ -56,8 +57,9 @@
/**
* Search and get a switch object with DPID.
- * @param dpid DPID of the switch
+ * @param dpid DPID of the switch
*/
+ @Override
public ISwitchObject searchSwitch(String dpid) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
@@ -69,10 +71,11 @@
/**
* Search and get an active switch object with DPID.
- * @param dpid DPID of the switch
+ * @param dpid DPID of the switch
*/
+ @Override
public ISwitchObject searchActiveSwitch(String dpid) {
-
+
ISwitchObject sw = searchSwitch(dpid);
if ((sw != null) &&
sw.getState().equals(SwitchState.ACTIVE.toString())) {
@@ -84,6 +87,7 @@
/**
* Get all switch objects.
*/
+ @Override
public Iterable<ISwitchObject> getAllSwitches() {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
@@ -93,11 +97,12 @@
/**
* Get all active switch objects.
*/
+ @Override
public Iterable<ISwitchObject> getActiveSwitches() {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
-
+
for (ISwitchObject sw: switches) {
if(sw.getState().equals(SwitchState.ACTIVE.toString())) {
activeSwitches.add(sw);
@@ -109,11 +114,12 @@
/**
* Get all inactive switch objects.
*/
+ @Override
public Iterable<ISwitchObject> getInactiveSwitches() {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();
-
+
for (ISwitchObject sw: switches) {
if(sw.getState().equals(SwitchState.INACTIVE.toString())) {
inactiveSwitches.add(sw);
@@ -125,6 +131,7 @@
/**
* Get all flow entries' objects where their switches are not updated.
*/
+ @Override
public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
//TODO: Should use an enum for flow_switch_state
@@ -135,14 +142,15 @@
* Remove specified switch.
* @param sw switch object to remove
*/
+ @Override
public void removeSwitch(ISwitchObject sw) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- fg.removeVertex(sw.asVertex());
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ fg.removeVertex(sw.asVertex());
}
-
+
@Override
public IPortObject newPort(String dpid, Short portNumber) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
IPortObject obj = fg.addVertex(null,IPortObject.class);
if (obj != null) {
obj.setType("port");
@@ -150,17 +158,18 @@
obj.setPortId(id);
obj.setNumber(portNumber);
}
- return obj;
-
+ return obj;
+
}
/**
* Create a port having specified port number.
* @param portNumber port number
*/
+ @Override
@Deprecated
public IPortObject newPort(Short portNumber) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
IPortObject obj = fg.addVertex(null,IPortObject.class);
if (obj != null) {
obj.setType("port");
@@ -174,6 +183,7 @@
* @param dpid DPID of a switch
* @param number port number of the switch's port
*/
+ @Override
public IPortObject searchPort(String dpid, Short number) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
if ( fg == null ) return null;
@@ -190,17 +200,19 @@
* Remove the specified switch port.
* @param port switch port object to remove
*/
+ @Override
public void removePort(IPortObject port) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
// EventGraph<TitanGraph> eg = conn.getEventGraph();
- if (fg != null) fg.removeVertex(port.asVertex());
+ if (fg != null) fg.removeVertex(port.asVertex());
}
/**
* Create and return a device object.
*/
+ @Override
public IDeviceObject newDevice() {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
IDeviceObject obj = fg.addVertex(null,IDeviceObject.class);
if (obj != null) obj.setType("device");
return obj;
@@ -210,6 +222,7 @@
* Search and get a device object having specified MAC address.
* @param macAddr MAC address to search and get
*/
+ @Override
public IDeviceObject searchDevice(String macAddr) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
if ( fg == null ) return null;
@@ -224,8 +237,9 @@
/**
* Get all devices.
*/
+ @Override
public Iterable<IDeviceObject> getDevices() {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
return fg != null ? fg.getVertices("type","device",IDeviceObject.class) : null;
}
@@ -233,15 +247,16 @@
* Remove the specified device.
* @param dev a device object to remove
*/
+ @Override
public void removeDevice(IDeviceObject dev) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- if (fg != null) fg.removeVertex(dev.asVertex());
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ if (fg != null) fg.removeVertex(dev.asVertex());
}
-
+
public IIpv4Address newIpv4Address() {
return newVertex("ipv4Address", IIpv4Address.class);
}
-
+
private <T extends IBaseObject> T newVertex(String type, Class<T> vertexType) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
T newVertex = fg.addVertex(null, vertexType);
@@ -250,15 +265,15 @@
}
return newVertex;
}
-
+
public IIpv4Address searchIpv4Address(int intIpv4Address) {
return searchForVertex("ipv4_address", intIpv4Address, IIpv4Address.class);
}
-
+
private <T> T searchForVertex(String propertyName, Object propertyValue, Class<T> vertexType) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
if (fg != null) {
- Iterator<T> it =
+ Iterator<T> it =
fg.getVertices(propertyName, propertyValue, vertexType).iterator();
if (it.hasNext()) {
return it.next();
@@ -266,7 +281,7 @@
}
return null;
}
-
+
public IIpv4Address ensureIpv4Address(int intIpv4Address) {
IIpv4Address ipv4Vertex = searchIpv4Address(intIpv4Address);
if (ipv4Vertex == null) {
@@ -275,7 +290,7 @@
}
return ipv4Vertex;
}
-
+
public void removeIpv4Address(IIpv4Address ipv4Address) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
fg.removeVertex(ipv4Address.asVertex());
@@ -284,8 +299,9 @@
/**
* Create and return a flow path object.
*/
+ @Override
public IFlowPath newFlowPath() {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
IFlowPath flowPath = fg.addVertex(null, IFlowPath.class);
if (flowPath != null) flowPath.setType("flow");
return flowPath;
@@ -295,6 +311,7 @@
* Search and get a flow path object with specified flow ID.
* @param flowId flow ID to search
*/
+ @Override
public IFlowPath searchFlowPath(FlowId flowId) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
if ( fg == null ) return null;
@@ -310,21 +327,23 @@
* Get a flow path object with a flow entry.
* @param flowEntry flow entry object
*/
+ @Override
public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
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);
+ pipe, IFlowPath.class);
return r.iterator().hasNext() ? r.iterator().next() : null;
}
/**
* Get all flow path objects.
*/
- public Iterable<IFlowPath> getAllFlowPaths() {
+ @Override
+ public Iterable<IFlowPath> getAllFlowPaths() {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
Iterable<IFlowPath> flowPaths = fg.getVertices("type", "flow", IFlowPath.class);
-
+
List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();
for (IFlowPath fp: flowPaths) {
@@ -339,6 +358,7 @@
* Remove the specified flow path.
* @param flowPath flow path object to remove
*/
+ @Override
public void removeFlowPath(IFlowPath flowPath) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
fg.removeVertex(flowPath.asVertex());
@@ -347,8 +367,9 @@
/**
* Create and return a flow entry object.
*/
+ @Override
public IFlowEntry newFlowEntry() {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
IFlowEntry flowEntry = fg.addVertex(null, IFlowEntry.class);
if (flowEntry != null) flowEntry.setType("flow_entry");
return flowEntry;
@@ -358,6 +379,7 @@
* Search and get a flow entry object with flow entry ID.
* @param flowEntryId flow entry ID to search
*/
+ @Override
public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
if ( fg == null ) return null;
@@ -372,9 +394,10 @@
/**
* Get all flow entry objects.
*/
+ @Override
public Iterable<IFlowEntry> getAllFlowEntries() {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
+
return fg.getVertices("type", "flow_entry", IFlowEntry.class);
}
@@ -382,21 +405,24 @@
* Remove the specified flow entry.
* @param flowEntry flow entry object to remove
*/
+ @Override
public void removeFlowEntry(IFlowEntry flowEntry) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
fg.removeVertex(flowEntry.asVertex());
}
-
+
/**
* Get the instance of GraphDBConnection assigned to this class.
*/
+ @Override
public IDBConnection getDBConnection() {
return conn;
}
-
+
/**
* Commit changes for the graph.
*/
+ @Override
public void commit() {
conn.commit();
}
@@ -404,6 +430,7 @@
/**
* Rollback changes for the graph.
*/
+ @Override
public void rollback() {
conn.rollback();
}
@@ -411,6 +438,7 @@
/**
* Close the connection of the assigned GraphDBConnection.
*/
+ @Override
public void close() {
conn.close();
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/web/TopoDevicesResource.java b/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
similarity index 90%
rename from src/main/java/net/onrc/onos/ofcontroller/devicemanager/web/TopoDevicesResource.java
rename to src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
index 0d95e49..10e250e 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/web/TopoDevicesResource.java
+++ b/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
@@ -1,4 +1,4 @@
-package net.onrc.onos.ofcontroller.devicemanager.web;
+package net.onrc.onos.graph.web;
import java.util.Iterator;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
index 13b9182..2eddadf 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
@@ -2,6 +2,7 @@
import net.floodlightcontroller.devicemanager.IDevice;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.devicemanager.OnosDevice;
public interface IDeviceStorage extends INetMapStorage {
@@ -12,5 +13,7 @@
public IDeviceObject getDeviceByMac(String mac);
public IDeviceObject getDeviceByIP(int ipv4Address);
public void changeDeviceAttachments(IDevice device);
- public void changeDeviceIPv4Address(IDevice device);
+ public void changeDeviceIPv4Address(IDevice device);
+
+ public void addOnosDevice(OnosDevice onosDevice);
}
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 a6203ba..65750e2 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -213,6 +213,7 @@
public void setIpv4Address(int ipv4Address);
@JsonIgnore
+ //@GremlinGroovy("it.in('hasAddress')")
@Adjacency(label = "hasAddress", direction = Direction.IN)
public IDeviceObject getDevice();
}
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 3eaf79d..e915614 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
@@ -2,6 +2,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import net.floodlightcontroller.devicemanager.IDevice;
@@ -13,6 +14,8 @@
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.devicemanager.OnosDevice;
import org.openflow.util.HexString;
import org.slf4j.Logger;
@@ -327,4 +330,102 @@
}
}
}
+
+ /**
+ * Takes an {@link OnosDevice} and adds it into the database. There is no
+ * checking of the database data and removing old data - an
+ * {@link OnosDevice} basically corresponds to a packet we've just seen,
+ * and we need to add that information into the database.
+ */
+ @Override
+ public void addOnosDevice(OnosDevice onosDevice) {
+ String macAddress = HexString.toHexString(onosDevice.getMacAddress().toBytes());
+
+ //if the switch port we try to attach a new device already has a link, then stop adding device
+ IPortObject portObject1 = ope.searchPort(HexString.toHexString(
+ onosDevice.getSwitchDPID()), onosDevice.getSwitchPort());
+
+ if (portObject1.getLinkedPorts().iterator().hasNext()) {
+ log.debug("stop adding OnosDevice: {} due to there is a link to: {}",
+ onosDevice, portObject1.getLinkedPorts().iterator().next().getPortId());
+ return;
+ }
+
+ log.debug("addOnosDevice: {}", onosDevice);
+
+ try {
+ IDeviceObject device = ope.searchDevice(macAddress);
+
+ if (device == null) {
+ device = ope.newDevice();
+ device.setType("device");
+ device.setState("ACTIVE");
+ device.setMACAddress(macAddress);
+ }
+
+ // Check if the device has the IP address, add it if it doesn't
+ if (onosDevice.getIpv4Address() != null) {
+ boolean hasIpAddress = false;
+ for (IIpv4Address ipv4Address : device.getIpv4Addresses()) {
+ if (ipv4Address.getIpv4Address() == onosDevice.getIpv4Address().intValue()) {
+ hasIpAddress = true;
+ break;
+ }
+ }
+
+ if (!hasIpAddress) {
+ IIpv4Address ipv4Address = ope.ensureIpv4Address(onosDevice.getIpv4Address().intValue());
+ IDeviceObject oldDevice = ipv4Address.getDevice();
+ if (oldDevice != null && oldDevice.getMACAddress() != macAddress) {
+ oldDevice.removeIpv4Address(ipv4Address);
+ }
+ device.addIpv4Address(ipv4Address);
+ }
+ }
+
+ // Check if the device has the attachment point, add it if not
+ // TODO single attachment point for now, extend to multiple later
+ String switchDpid = HexString.toHexString(onosDevice.getSwitchDPID());
+ boolean hasAttachmentPoint = false;
+ Iterator<IPortObject> it = device.getAttachedPorts().iterator();
+ if (it.hasNext()) {
+ IPortObject existingPort = it.next();
+ if (existingPort != null) {
+ ISwitchObject existingSwitch = existingPort.getSwitch();
+ if (!existingSwitch.getDPID().equals(switchDpid) ||
+ existingPort.getNumber() != onosDevice.getSwitchPort()) {
+ existingPort.removeDevice(device);
+ }
+ else {
+ hasAttachmentPoint = true;
+ }
+ }
+ }
+
+ /*
+ for (IPortObject portObject : device.getAttachedPorts()) {
+ ISwitchObject switchObject = portObject.getSwitch();
+ if (switchObject.getDPID().equals(switchDpid)
+ && portObject.getNumber() == onosDevice.getSwitchPort()) {
+ hasAttachmentPoint = true;
+ break;
+ }
+ }
+ */
+
+ if (!hasAttachmentPoint) {
+ IPortObject portObject = ope.searchPort(switchDpid, onosDevice.getSwitchPort());
+ if (portObject != null) {
+ portObject.setDevice(device);
+ }
+ }
+
+ ope.commit();
+ }
+ catch (TitanException e) {
+ log.error("addOnosDevice {} failed:", macAddress, e);
+ ope.rollback();
+ }
+ }
+
}
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 67b3ff0..bf6e2e9 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
@@ -6,6 +6,7 @@
import net.floodlightcontroller.routing.Link;
import net.onrc.onos.graph.DBOperation;
import net.onrc.onos.ofcontroller.core.ILinkStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
@@ -113,11 +114,28 @@
return addLink(link, null);
}
+ private void deleteDeviceOnPort(Long dpid, Short number)
+ {
+ IPortObject srcPortObject = op.searchPort(HexString.toHexString(dpid), number);
+ if (srcPortObject.getDevices().iterator().hasNext()) {
+ for (IDeviceObject deviceObject: srcPortObject.getDevices()) {
+ srcPortObject.removeDevice(deviceObject);
+ log.debug("delete Device "+ deviceObject.getMACAddress() +
+ " from sw: {} port: {} due to a new link added",
+ dpid, number);
+ }
+ }
+ }
+
@Override
public boolean addLink(Link link, LinkInfo linfo) {
boolean success = false;
try {
+ //delete the Device attachment points for the related switch and port
+ deleteDeviceOnPort(link.getSrc(),link.getSrcPort());
+ deleteDeviceOnPort(link.getDst(),link.getDstPort());
+
if (addLinkImpl(link)) {
// Set LinkInfo only if linfo is non-null.
if (linfo != null && (! setLinkInfoImpl(link, linfo))) {
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 1f7f783..cb535b2 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
@@ -26,12 +26,10 @@
protected DBOperation op;
protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
- /**
- * *
- * Initialize function. Before you use this class, please call this method
- *
- * @param conf configuration file for Cassandra DB
- */
+ /***
+ * Initialize function. Before you use this class, please call this method
+ * @param conf configuration file for Cassandra DB
+ */
@Override
public void init(final String dbStore, final String conf) {
op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
@@ -43,25 +41,26 @@
* Finalize/close function. After you use this class, please call this method.
* It will close the DB connection.
*/
+ @Override
public void finalize() {
close();
}
-
+
/***
* Finalize/close function. After you use this class, please call this method.
* It will close the DB connection. This is for Java garbage collection.
*/
@Override
public void close() {
- op.close();
+ op.close();
}
-
+
// Method designing policy:
// op.commit() and op.rollback() MUST called in public (first-class) methods.
// A first-class method MUST NOT call other first-class method.
// Routine process should be implemented in private method.
// A private method MUST NOT call commit or rollback.
-
+
/***
* This function is for updating the switch into the DB.
* @param dpid The switch dpid you want to update from the DB
@@ -72,7 +71,7 @@
* Jono, 11/8/2013
* We don't need this update method that demultiplexes DM_OPERATIONS,
* we can have clients just call the required methods directly.
- * We especially don't need this update method to re-implement
+ * We especially don't need this update method to re-implement
* the functions of other methods.
*/
@Deprecated
@@ -80,7 +79,7 @@
public boolean updateSwitch(String dpid, SwitchState state, DM_OPERATION dmope) {
boolean success = false;
ISwitchObject sw = null;
-
+
log.info("SwitchStorage:update {} dpid:{}", dmope, dpid);
switch(dmope) {
case UPDATE:
@@ -130,33 +129,33 @@
break;
default:
}
-
+
return success;
}
-
+
@Override
public boolean addSwitch(IOFSwitch sw) {
boolean success = false;
-
+
String dpid = sw.getStringId();
log.info("SwitchStorage:addSwitch(): dpid {} ", dpid);
-
+
try {
ISwitchObject curr = op.searchSwitch(dpid);
if (curr != null) {
- //If existing the switch. set The SW state ACTIVE.
+ //If existing the switch. set The SW state ACTIVE.
log.info("SwitchStorage:addSwitch dpid:{} already exists", dpid);
setSwitchStateImpl(curr, SwitchState.ACTIVE);
} else {
curr = addSwitchImpl(dpid);
}
-
+
for (OFPhysicalPort port: sw.getPorts()) {
//addPort(dpid, port);
addPortImpl(curr, port);
}
-
+
// XXX for now delete devices when we change a port to prevent
// having stale devices.
DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
@@ -168,14 +167,14 @@
deviceStorage.removeDeviceImpl(deviceStorage.getDeviceByMac(deviceObject.getMACAddress()));
}
}
-
+
op.commit();
success = true;
} catch (Exception e) {
op.rollback();
log.error("SwitchStorage:addSwitch dpid:{} failed", dpid, e);
}
-
+
return success;
}
@@ -186,16 +185,16 @@
// This method is only called by tests, so we probably don't need it.
// If we need both addSwitch interfaces, one should call the other
// rather than implementing the same logic twice.
- @Deprecated
+ @Deprecated
@Override
public boolean addSwitch(String dpid) {
boolean success = false;
-
+
log.info("SwitchStorage:addSwitch(): dpid {} ", dpid);
try {
ISwitchObject sw = op.searchSwitch(dpid);
if (sw != null) {
- //If existing the switch. set The SW state ACTIVE.
+ //If existing the switch. set The SW state ACTIVE.
log.info("SwitchStorage:addSwitch dpid:{} already exists", dpid);
setSwitchStateImpl(sw, SwitchState.ACTIVE);
} else {
@@ -208,7 +207,7 @@
e.printStackTrace();
log.error("SwitchStorage:addSwitch dpid:{} failed", dpid, e);
}
-
+
return success;
}
@@ -219,7 +218,7 @@
@Override
public boolean deleteSwitch(String dpid) {
boolean success = false;
-
+
try {
ISwitchObject sw = op.searchSwitch(dpid);
if (sw != null) {
@@ -232,18 +231,19 @@
e.printStackTrace();
log.error("SwitchStorage:deleteSwitch {} failed", dpid);
}
-
+
return success;
}
-
+
+ @Override
public boolean deactivateSwitch(String dpid) {
boolean success = false;
-
+
try {
ISwitchObject switchObject = op.searchSwitch(dpid);
if (switchObject != null) {
setSwitchStateImpl(switchObject, SwitchState.INACTIVE);
-
+
for (IPortObject portObject : switchObject.getPorts()) {
portObject.setState("INACTIVE");
}
@@ -258,16 +258,17 @@
op.rollback();
log.error("SwitchStorage:deactivateSwitch {} failed", dpid, e);
}
-
+
return success;
}
+ @Override
public boolean updatePort(String dpid, short portNum, int state, String desc) {
boolean success = false;
-
+
try {
ISwitchObject sw = op.searchSwitch(dpid);
-
+
if (sw != null) {
IPortObject p = sw.getPort(portNum);
log.info("SwitchStorage:updatePort dpid:{} port:{}", dpid, portNum);
@@ -283,7 +284,7 @@
op.rollback();
e.printStackTrace();
log.error("SwitchStorage:addPort dpid:{} port:{} failed", dpid, portNum);
- }
+ }
return success;
}
@@ -296,7 +297,7 @@
@Override
public boolean addPort(String dpid, OFPhysicalPort phport) {
boolean success = false;
-
+
if(((OFPortConfig.OFPPC_PORT_DOWN.getValue() & phport.getConfig()) > 0) ||
((OFPortState.OFPPS_LINK_DOWN.getValue() & phport.getState()) > 0)) {
// just dispatch to deletePort()
@@ -304,22 +305,22 @@
// DB with the correct info and port state.
return deletePort(dpid, phport.getPortNumber());
}
-
+
try {
ISwitchObject sw = op.searchSwitch(dpid);
-
+
if (sw != null) {
IPortObject portObject = addPortImpl(sw, phport);
-
+
// XXX for now delete devices when we change a port to prevent
// having stale devices.
DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
deviceStorage.init("","");
-
+
for (IDeviceObject deviceObject : portObject.getDevices()) {
deviceStorage.removeDevice(deviceObject);
}
-
+
op.commit();
success = true;
} else {
@@ -330,7 +331,7 @@
e.printStackTrace();
log.error("SwitchStorage:addPort dpid:{} port:{} failed", dpid, phport.getPortNumber());
}
-
+
return success;
}
@@ -342,19 +343,19 @@
@Override
public boolean deletePort(String dpid, short port) {
boolean success = false;
-
+
DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
deviceStorage.init("","");
-
+
try {
ISwitchObject sw = op.searchSwitch(dpid);
-
+
if (sw != null) {
IPortObject p = sw.getPort(port);
if (p != null) {
log.info("SwitchStorage:deletePort dpid:{} port:{} found and set INACTIVE", dpid, port);
p.setState("INACTIVE");
-
+
// XXX for now delete devices when we change a port to prevent
// having stale devices.
for (IDeviceObject d : p.getDevices()) {
@@ -363,7 +364,7 @@
op.commit();
}
}
-
+
success = true;
} catch (Exception e) {
op.rollback();
@@ -404,7 +405,7 @@
return null;
}
}
-
+
private void setSwitchStateImpl(ISwitchObject sw, SwitchState state) {
if (sw != null && state != null) {
sw.setState(state.toString());
@@ -412,7 +413,7 @@
sw.getDPID(), state.toString());
}
}
-
+
private void deleteSwitchImpl(ISwitchObject sw) {
if (sw != null) {
op.removeSwitch(sw);
@@ -421,40 +422,40 @@
}
}
-
+
private IPortObject addPortImpl(ISwitchObject sw, OFPhysicalPort phport) {
IPortObject portObject = op.searchPort(sw.getDPID(), phport.getPortNumber());
-
- log.info("SwitchStorage:addPort dpid:{} port:{}",
+
+ log.info("SwitchStorage:addPort dpid:{} port:{}",
sw.getDPID(), phport.getPortNumber());
-
+
if (portObject != null) {
setPortStateImpl(portObject, phport.getState(), phport.getName());
portObject.setState("ACTIVE");
-
+
// This a convoluted way of checking if the port is attached
- // or not, but doing it this way avoids using the
+ // or not, but doing it this way avoids using the
// ISwitchObject.getPort method which uses GremlinGroovy query
// and takes forever.
boolean attached = false;
for (IPortObject portsOnSwitch : sw.getPorts()) {
- if (portsOnSwitch.getPortId().equals(portObject.getPortId())) {
+ if (portsOnSwitch.getPortId().equals( portObject.getPortId() )) {
attached = true;
break;
}
}
-
+
if (!attached) {
sw.addPort(portObject);
}
-
+
/*
if (sw.getPort(phport.getPortNumber()) == null) {
// The port exists but the switch has no "on" link to it
sw.addPort(portObject);
}*/
-
- log.info("SwitchStorage:addPort dpid:{} port:{} exists setting as ACTIVE",
+
+ log.info("SwitchStorage:addPort dpid:{} port:{} exists setting as ACTIVE",
sw.getDPID(), phport.getPortNumber());
} else {
//addPortImpl(sw, phport.getPortNumber());
@@ -465,13 +466,13 @@
log.info("SwitchStorage:addPort dpid:{} port:{} done",
sw.getDPID(), phport.getPortNumber());
}
-
+
return portObject;
}
// TODO There's an issue here where a port with that ID could already
// exist when we try to add this one (because it's left over from an
// old topology). We need to remove an old port with the same ID when
- // we add the new port. Also it seems that old ports like this are
+ // we add the new port. Also it seems that old ports like this are
// never cleaned up and will remain in the DB in the ACTIVE state forever.
/*private IPortObject addPortImpl(ISwitchObject sw, short portNum) {
IPortObject p = op.newPort(sw.getDPID(), portNum);
@@ -479,7 +480,7 @@
sw.addPort(p);
log.info("SwitchStorage:addPortImpl dpid:{} port:{} done",
sw.getDPID(), portNum);
-
+
return p;
}*/
@@ -491,9 +492,9 @@
if (desc != null) {
port.setDesc(desc);
}
-
+
log.info("SwitchStorage:setPortStateImpl port:{} state:{} desc:{} done",
new Object[] {port.getPortId(), state, desc});
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/web/OnosInternalWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/core/web/OnosInternalWebRoutable.java
new file mode 100644
index 0000000..78bb02b
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/web/OnosInternalWebRoutable.java
@@ -0,0 +1,22 @@
+package net.onrc.onos.ofcontroller.core.web;
+
+import org.restlet.Context;
+import org.restlet.Restlet;
+import org.restlet.routing.Router;
+
+import net.floodlightcontroller.restserver.RestletRoutable;
+
+public class OnosInternalWebRoutable implements RestletRoutable {
+ @Override
+ public String basePath() {
+ return "/wm/onos/internal";
+ }
+
+ @Override
+ public Restlet getRestlet(Context context) {
+ Router router = new Router(context);
+ // Following added by ONOS
+ router.attach("/clearflowtable/json", ClearFlowTableResource.class);
+ return router;
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/IOnosDeviceService.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/IOnosDeviceService.java
new file mode 100644
index 0000000..1e40aa5
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/IOnosDeviceService.java
@@ -0,0 +1,14 @@
+package net.onrc.onos.ofcontroller.devicemanager;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+/**
+ * {@link OnosDeviceManager} doesn't yet provide any API to fellow modules,
+ * however making it export a dummy service means we can specify it as
+ * a dependency of Forwarding
+ * @author jono
+ *
+ */
+public interface IOnosDeviceService extends IFloodlightService {
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java
new file mode 100644
index 0000000..34d2c38
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java
@@ -0,0 +1,274 @@
+/**
+* Copyright 2011,2012, Big Switch Networks, Inc.
+* Originally created by David Erickson, Stanford University
+*
+* Licensed under the Apache License, Version 2.0 (the "License"); you may
+* not use this file except in compliance with the License. You may obtain
+* a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+**/
+
+package net.onrc.onos.ofcontroller.devicemanager;
+
+import java.util.Date;
+
+import net.floodlightcontroller.devicemanager.internal.Entity;
+import net.floodlightcontroller.packet.IPv4;
+import net.floodlightcontroller.util.MACAddress;
+
+/**
+ * An entity on the network is a visible trace of a device that corresponds
+ * to a packet received from a particular interface on the edge of a network,
+ * with a particular VLAN tag, and a particular MAC address, along with any
+ * other packet characteristics we might want to consider as helpful for
+ * disambiguating devices.
+ *
+ * Entities are the most basic element of devices; devices consist of one or
+ * more entities. Entities are immutable once created, except for the last
+ * seen timestamp.
+ *
+ * @author readams
+ *
+ */
+public class OnosDevice { //implements Comparable<OnosDevice> {
+ /**
+ * Timeout for computing {@link Entity#activeSince}.
+ * @see {@link Entity#activeSince}
+ */
+ private static int ACTIVITY_TIMEOUT = 30000;
+
+ /**
+ * The MAC address associated with this entity
+ */
+ private MACAddress macAddress;
+
+ /**
+ * The IP address associated with this entity, or null if no IP learned
+ * from the network observation associated with this entity
+ */
+ private Integer ipv4Address;
+
+ /**
+ * The VLAN tag on this entity, or null if untagged
+ */
+ private Short vlan;
+
+ /**
+ * The DPID of the switch for the ingress point for this entity,
+ * or null if not present
+ */
+ private long switchDPID;
+
+ /**
+ * The port number of the switch for the ingress point for this entity,
+ * or null if not present
+ */
+ private short switchPort;
+
+ /**
+ * The last time we observed this entity on the network
+ */
+ private Date lastSeenTimestamp;
+
+ /**
+ * The time between {@link Entity#activeSince} and
+ * {@link Entity#lastSeenTimestamp} is a period of activity for this
+ * entity where it was observed repeatedly. If, when the entity is
+ * observed, the is longer ago than the activity timeout,
+ * {@link Entity#lastSeenTimestamp} and {@link Entity#activeSince} will
+ * be set to the current time.
+ */
+ private Date activeSince;
+
+ private int hashCode = 0;
+
+ // ************
+ // Constructors
+ // ************
+
+ /**
+ * Create a new entity
+ *
+ * @param macAddress
+ * @param vlan
+ * @param ipv4Address
+ * @param switchDPID
+ * @param switchPort
+ * @param lastSeenTimestamp
+ */
+ public OnosDevice(MACAddress macAddress, Short vlan,
+ Integer ipv4Address, Long switchDPID, short switchPort,
+ Date lastSeenTimestamp) {
+ this.macAddress = macAddress;
+ this.ipv4Address = ipv4Address;
+ this.vlan = vlan;
+ this.switchDPID = switchDPID;
+ this.switchPort = switchPort;
+ this.lastSeenTimestamp = lastSeenTimestamp;
+ this.activeSince = lastSeenTimestamp;
+ }
+
+ // ***************
+ // Getters/Setters
+ // ***************
+
+ public MACAddress getMacAddress() {
+ return macAddress;
+ }
+
+ public Integer getIpv4Address() {
+ return ipv4Address;
+ }
+
+ public Short getVlan() {
+ return vlan;
+ }
+
+ public Long getSwitchDPID() {
+ return switchDPID;
+ }
+
+ public short getSwitchPort() {
+ return switchPort;
+ }
+
+ public Date getLastSeenTimestamp() {
+ return lastSeenTimestamp;
+ }
+
+ /**
+ * Set the last seen timestamp and also update {@link Entity#activeSince}
+ * if appropriate
+ * @param lastSeenTimestamp the new last seen timestamp
+ * @see {@link Entity#activeSince}
+ */
+ public void setLastSeenTimestamp(Date lastSeenTimestamp) {
+ if (activeSince == null ||
+ (activeSince.getTime() + ACTIVITY_TIMEOUT) <
+ lastSeenTimestamp.getTime())
+ this.activeSince = lastSeenTimestamp;
+ this.lastSeenTimestamp = lastSeenTimestamp;
+ }
+
+ public Date getActiveSince() {
+ return activeSince;
+ }
+
+ public void setActiveSince(Date activeSince) {
+ this.activeSince = activeSince;
+ }
+
+ /*
+ @Override
+ public int hashCode() {
+ if (hashCode != 0) return hashCode;
+ final int prime = 31;
+ hashCode = 1;
+ hashCode = prime * hashCode
+ + ((ipv4Address == null) ? 0 : ipv4Address.hashCode());
+ //hashCode = prime * hashCode + (int) (macAddress ^ (macAddress >>> 32));
+ hashCode = prime * macAddress.hashCode();
+ hashCode = prime * hashCode + (int) (switchDPID ^ (switchDPID >>> 32));
+ hashCode = prime * hashCode + switchPort;
+ hashCode = prime * hashCode + ((vlan == null) ? 0 : vlan.hashCode());
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ Entity other = (Entity) obj;
+ if (hashCode() != other.hashCode()) return false;
+ if (ipv4Address == null) {
+ if (other.ipv4Address != null) return false;
+ } else if (!ipv4Address.equals(other.ipv4Address)) return false;
+ if (macAddress != other.macAddress) return false;
+ if (switchDPID == null) {
+ if (other.switchDPID != null) return false;
+ } else if (!switchDPID.equals(other.switchDPID)) return false;
+ if (switchPort == null) {
+ if (other.switchPort != null) return false;
+ } else if (!switchPort.equals(other.switchPort)) return false;
+ if (vlan == null) {
+ if (other.vlan != null) return false;
+ } else if (!vlan.equals(other.vlan)) return false;
+ return true;
+ }
+ */
+
+
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Entity [macAddress=");
+ builder.append(macAddress.toString());
+ builder.append(", ipv4Address=");
+ builder.append(IPv4.fromIPv4Address(ipv4Address==null ?
+ 0 : ipv4Address.intValue()));
+ builder.append(", vlan=");
+ builder.append(vlan);
+ builder.append(", switchDPID=");
+ builder.append(switchDPID);
+ builder.append(", switchPort=");
+ builder.append(switchPort);
+ builder.append(", lastSeenTimestamp=");
+ builder.append(lastSeenTimestamp == null? "null" : lastSeenTimestamp.getTime());
+ builder.append(", activeSince=");
+ builder.append(activeSince == null? "null" : activeSince.getTime());
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /*
+ @Override
+ public int compareTo(OnosDevice o) {
+ if (macAddress < o.macAddress) return -1;
+ if (macAddress > o.macAddress) return 1;
+
+ int r;
+ if (switchDPID == null)
+ r = o.switchDPID == null ? 0 : -1;
+ else if (o.switchDPID == null)
+ r = 1;
+ else
+ r = switchDPID.compareTo(o.switchDPID);
+ if (r != 0) return r;
+
+ if (switchPort == null)
+ r = o.switchPort == null ? 0 : -1;
+ else if (o.switchPort == null)
+ r = 1;
+ else
+ r = switchPort.compareTo(o.switchPort);
+ if (r != 0) return r;
+
+ if (ipv4Address == null)
+ r = o.ipv4Address == null ? 0 : -1;
+ else if (o.ipv4Address == null)
+ r = 1;
+ else
+ r = ipv4Address.compareTo(o.ipv4Address);
+ if (r != 0) return r;
+
+ if (vlan == null)
+ r = o.vlan == null ? 0 : -1;
+ else if (o.vlan == null)
+ r = 1;
+ else
+ r = vlan.compareTo(o.vlan);
+ if (r != 0) return r;
+
+ return 0;
+ }*/
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
new file mode 100644
index 0000000..f75a2b0
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
@@ -0,0 +1,190 @@
+package net.onrc.onos.ofcontroller.devicemanager;
+
+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 net.floodlightcontroller.core.FloodlightContext;
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFMessageListener;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IUpdate;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.packet.ARP;
+import net.floodlightcontroller.packet.DHCP;
+import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.packet.IPv4;
+import net.floodlightcontroller.packet.UDP;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
+
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFPacketIn;
+import org.openflow.protocol.OFType;
+
+public class OnosDeviceManager implements IFloodlightModule, IOFMessageListener,
+ IOnosDeviceService {
+ private IDeviceStorage deviceStorage;
+
+ private IFloodlightProviderService floodlightProvider;
+
+ private class OnosDeviceUpdate implements IUpdate {
+ private OnosDevice device;
+
+ public OnosDeviceUpdate(OnosDevice device) {
+ this.device = device;
+ }
+
+ @Override
+ public void dispatch() {
+ deviceStorage.addOnosDevice(device);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "onosdevicemanager";
+ }
+
+ @Override
+ public boolean isCallbackOrderingPrereq(OFType type, String name) {
+ // We want link discovery to consume LLDP first otherwise we'll
+ // end up reading bad device info from LLDP packets
+ return type == OFType.PACKET_IN && "linkdiscovery".equals(name);
+ }
+
+ @Override
+ public boolean isCallbackOrderingPostreq(OFType type, String name) {
+ return type == OFType.PACKET_IN &&
+ ("proxyarpmanager".equals(name) || "onosforwarding".equals(name));
+ }
+
+ @Override
+ public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
+ if (msg.getType().equals(OFType.PACKET_IN)) {
+ OFPacketIn pi = (OFPacketIn) msg;
+
+ Ethernet eth = IFloodlightProviderService.bcStore.
+ get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+
+ return processPacketIn(sw, pi, eth);
+ }
+
+ return Command.CONTINUE;
+ }
+
+ private Command processPacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
+
+ // Extract source entity information
+ OnosDevice srcDevice =
+ getSourceDeviceFromPacket(eth, sw.getId(), pi.getInPort());
+ if (srcDevice == null)
+ return Command.STOP;
+
+ floodlightProvider.publishUpdate(new OnosDeviceUpdate(srcDevice));
+
+ return Command.CONTINUE;
+ }
+
+ /**
+ * Get IP address from packet if the packet is either an ARP
+ * or a DHCP packet
+ * @param eth
+ * @param dlAddr
+ * @return
+ */
+ private int getSrcNwAddr(Ethernet eth, long dlAddr) {
+ if (eth.getPayload() instanceof ARP) {
+ ARP arp = (ARP) eth.getPayload();
+ if ((arp.getProtocolType() == ARP.PROTO_TYPE_IP) &&
+ (Ethernet.toLong(arp.getSenderHardwareAddress()) == dlAddr)) {
+ return IPv4.toIPv4Address(arp.getSenderProtocolAddress());
+ }
+ } else if (eth.getPayload() instanceof IPv4) {
+ IPv4 ipv4 = (IPv4) eth.getPayload();
+ if (ipv4.getPayload() instanceof UDP) {
+ UDP udp = (UDP)ipv4.getPayload();
+ if (udp.getPayload() instanceof DHCP) {
+ DHCP dhcp = (DHCP)udp.getPayload();
+ if (dhcp.getOpCode() == DHCP.OPCODE_REPLY) {
+ return ipv4.getSourceAddress();
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Parse an entity from an {@link Ethernet} packet.
+ * @param eth the packet to parse
+ * @param sw the switch on which the packet arrived
+ * @param pi the original packetin
+ * @return the entity from the packet
+ */
+ private OnosDevice getSourceDeviceFromPacket(Ethernet eth,
+ long swdpid,
+ short port) {
+ byte[] dlAddrArr = eth.getSourceMACAddress();
+ long dlAddr = Ethernet.toLong(dlAddrArr);
+
+ // Ignore broadcast/multicast source
+ if ((dlAddrArr[0] & 0x1) != 0)
+ return null;
+
+ short vlan = eth.getVlanID();
+ int nwSrc = getSrcNwAddr(eth, dlAddr);
+ return new OnosDevice(MACAddress.valueOf(dlAddr),
+ ((vlan >= 0) ? vlan : null),
+ ((nwSrc != 0) ? nwSrc : null),
+ swdpid,
+ port,
+ new Date());
+ }
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+ List<Class<? extends IFloodlightService>> services =
+ new ArrayList<Class<? extends IFloodlightService>>();
+ services.add(IOnosDeviceService.class);
+ return services;
+ }
+
+ @Override
+ public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+ Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
+ new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+ impls.put(IOnosDeviceService.class, this);
+ return impls;
+ }
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+ List<Class<? extends IFloodlightService>> dependencies =
+ new ArrayList<Class<? extends IFloodlightService>>();
+ dependencies.add(IFloodlightProviderService.class);
+ return dependencies;
+ }
+
+ @Override
+ public void init(FloodlightModuleContext context)
+ throws FloodlightModuleException {
+ floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+
+ deviceStorage = new DeviceStorageImpl();
+ deviceStorage.init("");
+ }
+
+ @Override
+ public void startUp(FloodlightModuleContext context) {
+ floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+ }
+
+}
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 f458603..3337cf8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -8,13 +8,6 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.net.InetAddresses;
-
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitchListener;
@@ -25,7 +18,6 @@
import net.floodlightcontroller.core.util.SingletonTask;
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.devicemanager.IDeviceListener;
-import net.floodlightcontroller.devicemanager.IDeviceService;
import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.onrc.onos.graph.DBOperation;
@@ -36,10 +28,10 @@
import net.onrc.onos.graph.LocalTopologyEventListener;
import net.onrc.onos.ofcontroller.core.IDeviceStorage;
import net.onrc.onos.ofcontroller.core.ILinkStorage;
-import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
-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.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
@@ -52,6 +44,13 @@
import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
import net.onrc.onos.registry.controller.RegistryException;
+import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.net.InetAddresses;
+
public class NetworkGraphPublisher implements IDeviceListener,
IOFSwitchListener,
IOFSwitchPortListener,
@@ -63,7 +62,7 @@
protected ISwitchStorage swStore;
protected ILinkStorage linkStore;
protected final static Logger log = LoggerFactory.getLogger(NetworkGraphPublisher.class);
- protected IDeviceService deviceService;
+ //protected IDeviceService deviceService;
protected IControllerRegistryService registryService;
protected DBOperation op;
@@ -177,62 +176,63 @@
op.close();
}
- @Override
- public void linkDiscoveryUpdate(LDUpdate update) {
- Link lt = new Link(update.getSrc(),update.getSrcPort(),update.getDst(),update.getDstPort());
- //log.debug("{}:LinkDicoveryUpdate(): Updating Link {}",this.getClass(), lt);
-
- switch (update.getOperation()) {
- case LINK_REMOVED:
- log.debug("LinkDiscoveryUpdate(): Removing link {}", lt);
-
- if (linkStore.deleteLink(lt)) {
- // TODO publish DELETE_LINK event here
- TopologyElement topologyElement =
- new TopologyElement(update.getSrc(),
- update.getSrcPort(),
- update.getDst(),
- update.getDstPort());
- datagridService.notificationSendTopologyElementRemoved(topologyElement);
- }
- break;
- case LINK_UPDATED:
- log.debug("LinkDiscoveryUpdate(): Updating link {}", lt);
-
- LinkInfo linfo = linkStore.getLinkInfo(lt);
- // TODO update "linfo" using portState derived using "update"
- if (linkStore.update(lt, linfo, DM_OPERATION.UPDATE)) {
- // TODO publish UPDATE_LINK event here
- //
- // TODO NOTE: Here we assume that updated
- // link is UP.
- //
- TopologyElement topologyElement =
- new TopologyElement(update.getSrc(),
- update.getSrcPort(),
- update.getDst(),
- update.getDstPort());
- datagridService.notificationSendTopologyElementUpdated(topologyElement);
- }
- break;
- case LINK_ADDED:
- log.debug("LinkDiscoveryUpdate(): Adding link {}", lt);
-
- if (linkStore.addLink(lt)) {
- // TODO publish ADD_LINK event here
- TopologyElement topologyElement =
- new TopologyElement(update.getSrc(),
- update.getSrcPort(),
- update.getDst(),
- update.getDstPort());
- datagridService.notificationSendTopologyElementAdded(topologyElement);
- }
- break;
- default:
- break;
- }
+ @Override
+ public void linkDiscoveryUpdate(LDUpdate update) {
+ Link lt = new Link(update.getSrc(),update.getSrcPort(),update.getDst(),update.getDstPort());
+ //log.debug("{}:LinkDicoveryUpdate(): Updating Link {}",this.getClass(), lt);
- }
+ switch (update.getOperation()) {
+ case LINK_REMOVED:
+ log.debug("LinkDiscoveryUpdate(): Removing link {}", lt);
+
+ if (linkStore.deleteLink(lt)) {
+ // TODO publish DELETE_LINK event here
+ TopologyElement topologyElement =
+ new TopologyElement(update.getSrc(),
+ update.getSrcPort(),
+ update.getDst(),
+ update.getDstPort());
+ datagridService.notificationSendTopologyElementRemoved(topologyElement);
+ }
+ break;
+ case LINK_UPDATED:
+ log.debug("LinkDiscoveryUpdate(): Updating link {}", lt);
+
+ LinkInfo linfo = linkStore.getLinkInfo(lt);
+ // TODO update "linfo" using portState derived using "update"
+ if (linkStore.update(lt, linfo, DM_OPERATION.UPDATE)) {
+ // TODO publish UPDATE_LINK event here
+ //
+ // TODO NOTE: Here we assume that updated
+ // link is UP.
+ //
+ TopologyElement topologyElement =
+ new TopologyElement(update.getSrc(),
+ update.getSrcPort(),
+ update.getDst(),
+ update.getDstPort());
+ datagridService.notificationSendTopologyElementUpdated(topologyElement);
+ }
+ break;
+ case LINK_ADDED:
+ log.debug("LinkDiscoveryUpdate(): Adding link {}", lt);
+
+ if (linkStore.addLink(lt)) {
+ // TODO publish ADD_LINK event here
+ TopologyElement topologyElement =
+ new TopologyElement(update.getSrc(),
+ update.getSrcPort(),
+ update.getDst(),
+ update.getDstPort());
+ datagridService.notificationSendTopologyElementAdded(topologyElement);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ }
@Override
public void addedSwitch(IOFSwitch sw) {
@@ -434,7 +434,7 @@
Collection<Class<? extends IFloodlightService>> l =
new ArrayList<Class<? extends IFloodlightService>>();
l.add(IFloodlightProviderService.class);
- l.add(IDeviceService.class);
+ //l.add(IDeviceService.class);
l.add(IDatagridService.class);
l.add(IThreadPoolService.class);
return l;
@@ -455,7 +455,7 @@
floodlightProvider =
context.getServiceImpl(IFloodlightProviderService.class);
- deviceService = context.getServiceImpl(IDeviceService.class);
+ //deviceService = context.getServiceImpl(IDeviceService.class);
linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
threadPool = context.getServiceImpl(IThreadPoolService.class);
registryService = context.getServiceImpl(IControllerRegistryService.class);
@@ -479,7 +479,7 @@
Map<String, String> configMap = context.getConfigParams(this);
String cleanupNeeded = configMap.get(CleanupEnabled);
- deviceService.addListener(this);
+ //deviceService.addListener(this);
floodlightProvider.addOFSwitchListener(this);
linkDiscovery.addListener(this);
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 ec27a0f..194922b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -622,6 +622,12 @@
* @return the extracted Flow Entry State.
*/
public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
+ IFlowPath flowObj = flowEntryObj.getFlow();
+ if (flowObj == null)
+ return null;
+
+ String flowIdStr = flowObj.getFlowId();
+ //
String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Integer idleTimeout = flowEntryObj.getIdleTimeout();
Integer hardTimeout = flowEntryObj.getHardTimeout();
@@ -629,7 +635,8 @@
String userState = flowEntryObj.getUserState();
String switchState = flowEntryObj.getSwitchState();
- if ((flowEntryIdStr == null) ||
+ if ((flowIdStr == null) ||
+ (flowEntryIdStr == null) ||
(idleTimeout == null) ||
(hardTimeout == null) ||
(switchDpidStr == null) ||
@@ -641,10 +648,11 @@
FlowEntry flowEntry = new FlowEntry();
flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
+ flowEntry.setFlowId(new FlowId(flowIdStr));
flowEntry.setDpid(new Dpid(switchDpidStr));
flowEntry.setIdleTimeout(idleTimeout);
flowEntry.setHardTimeout(hardTimeout);
-
+
//
// Extract the match conditions
//
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 3538eb4..c36c53a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -460,7 +460,7 @@
*/
private void processFlowEntryEvents() {
FlowPath flowPath;
- FlowEntry updatedFlowEntry;
+ FlowEntry localFlowEntry;
//
// Update Flow Entries with previously unmatched Flow Entry updates
@@ -471,13 +471,15 @@
flowPath = allFlowPaths.get(flowEntry.flowId().value());
if (flowPath == null)
continue;
- updatedFlowEntry = updateFlowEntryAdd(flowPath, flowEntry);
- if (updatedFlowEntry == null) {
+ localFlowEntry = findFlowEntryAdd(flowPath, flowEntry);
+ if (localFlowEntry == null) {
remainingUpdates.put(flowEntry.flowEntryId().value(),
flowEntry);
continue;
}
- modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
+ if (updateFlowEntryAdd(flowPath, localFlowEntry, flowEntry)) {
+ modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
+ }
}
unmatchedFlowEntryAdd = remainingUpdates;
}
@@ -505,15 +507,17 @@
flowEntry);
break;
}
- updatedFlowEntry = updateFlowEntryAdd(flowPath, flowEntry);
- if (updatedFlowEntry == null) {
+ localFlowEntry = findFlowEntryAdd(flowPath, flowEntry);
+ if (localFlowEntry == null) {
// Flow Entry not found: keep the entry for later matching
unmatchedFlowEntryAdd.put(flowEntry.flowEntryId().value(),
flowEntry);
break;
}
- // Add the updated entry to the list of updated Flow Entries
- modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
+ if (updateFlowEntryAdd(flowPath, localFlowEntry, flowEntry)) {
+ // Add the updated Flow Path to the list of updated paths
+ modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
+ }
break;
case ENTRY_REMOVE:
@@ -527,32 +531,37 @@
// Flow Path not found: ignore the update
break;
}
- updatedFlowEntry = updateFlowEntryRemove(flowPath, flowEntry);
- if (updatedFlowEntry == null) {
+ localFlowEntry = findFlowEntryRemove(flowPath, flowEntry);
+ if (localFlowEntry == null) {
// Flow Entry not found: ignore it
break;
}
- modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
+ if (updateFlowEntryRemove(flowPath, localFlowEntry,
+ flowEntry)) {
+ // Add the updated Flow Path to the list of updated paths
+ modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
+ }
break;
}
}
}
/**
- * Update a Flow Entry because of an external ENTRY_ADD event.
+ * Find a Flow Entry that should be updated because of an external
+ * ENTRY_ADD event.
*
* @param flowPath the FlowPath for the Flow Entry to update.
- * @param flowEntry the FlowEntry with the new state.
- * @return the updated Flow Entry if found, otherwise null.
+ * @param newFlowEntry the FlowEntry with the new state.
+ * @return the Flow Entry that should be updated if found, otherwise null.
*/
- private FlowEntry updateFlowEntryAdd(FlowPath flowPath,
- FlowEntry flowEntry) {
+ private FlowEntry findFlowEntryAdd(FlowPath flowPath,
+ FlowEntry newFlowEntry) {
//
// Iterate over all Flow Entries and find a match.
//
for (FlowEntry localFlowEntry : flowPath.flowEntries()) {
if (! TopologyManager.isSameFlowEntryDataPath(localFlowEntry,
- flowEntry)) {
+ newFlowEntry)) {
continue;
}
@@ -561,27 +570,89 @@
//
if (localFlowEntry.isValidFlowEntryId()) {
if (localFlowEntry.flowEntryId().value() !=
- flowEntry.flowEntryId().value()) {
+ newFlowEntry.flowEntryId().value()) {
//
// Find a local Flow Entry, but the Flow Entry ID doesn't
// match. Keep looking.
//
continue;
}
- } else {
- // Update the Flow Entry ID
- FlowEntryId flowEntryId =
- new FlowEntryId(flowEntry.flowEntryId().value());
- localFlowEntry.setFlowEntryId(flowEntryId);
}
+ return localFlowEntry;
+ }
- //
- // 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());
+ return null; // Entry not found
+ }
+
+ /**
+ * Update a Flow Entry because of an external ENTRY_ADD event.
+ *
+ * @param flowPath the FlowPath for the Flow Entry to update.
+ * @param localFlowEntry the local Flow Entry to update.
+ * @param newFlowEntry the FlowEntry with the new state.
+ * @return true if the local Flow Entry was updated, otherwise false.
+ */
+ private boolean updateFlowEntryAdd(FlowPath flowPath,
+ FlowEntry localFlowEntry,
+ FlowEntry newFlowEntry) {
+ boolean updated = false;
+
+ if (localFlowEntry.flowEntryUserState() ==
+ FlowEntryUserState.FE_USER_DELETE) {
+ // Don't add-back a Flow Entry that is already deleted
+ return false;
+ }
+
+ if (! localFlowEntry.isValidFlowEntryId()) {
+ // Update the Flow Entry ID
+ FlowEntryId flowEntryId =
+ new FlowEntryId(newFlowEntry.flowEntryId().value());
+ localFlowEntry.setFlowEntryId(flowEntryId);
+ updated = true;
+ }
+
+ //
+ // Update the local Flow Entry, and keep state to check
+ // if the Flow Path has been installed.
+ //
+ if (localFlowEntry.flowEntryUserState() !=
+ newFlowEntry.flowEntryUserState()) {
+ localFlowEntry.setFlowEntryUserState(
+ newFlowEntry.flowEntryUserState());
+ updated = true;
+ }
+ if (localFlowEntry.flowEntrySwitchState() !=
+ newFlowEntry.flowEntrySwitchState()) {
+ localFlowEntry.setFlowEntrySwitchState(
+ newFlowEntry.flowEntrySwitchState());
checkIfInstalledFlowPaths.put(flowPath.flowId().value(), flowPath);
+ updated = true;
+ }
+
+ return updated;
+ }
+
+ /**
+ * Find a Flow Entry that should be updated because of an external
+ * ENTRY_REMOVE event.
+ *
+ * @param flowPath the FlowPath for the Flow Entry to update.
+ * @param newFlowEntry the FlowEntry with the new state.
+ * @return the Flow Entry that should be updated if found, otherwise null.
+ */
+ private FlowEntry findFlowEntryRemove(FlowPath flowPath,
+ FlowEntry newFlowEntry) {
+ //
+ // Iterate over all Flow Entries and find a match based on
+ // the Flow Entry ID.
+ //
+ for (FlowEntry localFlowEntry : flowPath.flowEntries()) {
+ if (! localFlowEntry.isValidFlowEntryId())
+ continue;
+ if (localFlowEntry.flowEntryId().value() !=
+ newFlowEntry.flowEntryId().value()) {
+ continue;
+ }
return localFlowEntry;
}
@@ -592,31 +663,32 @@
* Update a Flow Entry because of an external ENTRY_REMOVE event.
*
* @param flowPath the FlowPath for the Flow Entry to update.
- * @param flowEntry the FlowEntry with the new state.
- * @return the updated Flow Entry if found, otherwise null.
+ * @param localFlowEntry the local Flow Entry to update.
+ * @param newFlowEntry the FlowEntry with the new state.
+ * @return true if the local Flow Entry was updated, otherwise false.
*/
- private FlowEntry updateFlowEntryRemove(FlowPath flowPath,
- FlowEntry flowEntry) {
+ private boolean updateFlowEntryRemove(FlowPath flowPath,
+ FlowEntry localFlowEntry,
+ FlowEntry newFlowEntry) {
+ boolean updated = false;
+
//
- // Iterate over all Flow Entries and find a match based on
- // the Flow Entry ID.
+ // Update the local Flow Entry.
//
- for (FlowEntry localFlowEntry : flowPath.flowEntries()) {
- if (! localFlowEntry.isValidFlowEntryId())
- continue;
- if (localFlowEntry.flowEntryId().value() !=
- flowEntry.flowEntryId().value()) {
- continue;
- }
- //
- // Update the local Flow Entry.
- //
- localFlowEntry.setFlowEntryUserState(flowEntry.flowEntryUserState());
- localFlowEntry.setFlowEntrySwitchState(flowEntry.flowEntrySwitchState());
- return localFlowEntry;
+ if (localFlowEntry.flowEntryUserState() !=
+ newFlowEntry.flowEntryUserState()) {
+ localFlowEntry.setFlowEntryUserState(
+ newFlowEntry.flowEntryUserState());
+ updated = true;
+ }
+ if (localFlowEntry.flowEntrySwitchState() !=
+ newFlowEntry.flowEntrySwitchState()) {
+ localFlowEntry.setFlowEntrySwitchState(
+ newFlowEntry.flowEntrySwitchState());
+ updated = true;
}
- return null; // Entry not found
+ return updated;
}
/**
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 9df6cae..072e34f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -249,10 +249,17 @@
// in case the application didn't do it.
//
for (FlowEntry flowEntry : flowPath.flowEntries()) {
+ // The Flow Entry switch state
if (flowEntry.flowEntrySwitchState() ==
FlowEntrySwitchState.FE_SWITCH_UNKNOWN) {
flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED);
}
+ // The Flow Entry ID
+ if (! flowEntry.isValidFlowEntryId()) {
+ long id = getNextFlowEntryId();
+ flowEntry.setFlowEntryId(new FlowEntryId(id));
+ }
+ // The Flow ID
if (! flowEntry.isValidFlowId())
flowEntry.setFlowId(new FlowId(flowPath.flowId().value()));
}
@@ -406,32 +413,40 @@
//
// Process all entries
//
+ // TODO: For now we have to create an explicit FlowEntry copy so
+ // we don't modify the original FlowEntry.
+ // This should go away after we start using the OpenFlow Barrier
+ // mechnanism in the FlowPusher.
+ //
+ Kryo kryo = kryoFactory.newKryo();
for (Pair<IOFSwitch, FlowEntry> entry : entries) {
FlowEntry flowEntry = entry.second;
//
// Mark the Flow Entry that it has been pushed to the switch
//
- flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_UPDATED);
+ FlowEntry copyFlowEntry = kryo.copy(flowEntry);
+ copyFlowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_UPDATED);
//
// Write the Flow Entry to the Datagrid
//
- switch (flowEntry.flowEntryUserState()) {
+ switch (copyFlowEntry.flowEntryUserState()) {
case FE_USER_ADD:
- datagridService.notificationSendFlowEntryAdded(flowEntry);
+ datagridService.notificationSendFlowEntryAdded(copyFlowEntry);
break;
case FE_USER_MODIFY:
- datagridService.notificationSendFlowEntryUpdated(flowEntry);
+ datagridService.notificationSendFlowEntryUpdated(copyFlowEntry);
break;
case FE_USER_DELETE:
- datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
+ datagridService.notificationSendFlowEntryRemoved(copyFlowEntry.flowEntryId());
break;
case FE_USER_UNKNOWN:
assert(false);
break;
}
}
+ kryoFactory.deleteKryo(kryo);
}
/**
@@ -688,6 +703,11 @@
allValid = false;
break;
}
+ if (flowEntry.flowEntrySwitchState() !=
+ FlowEntrySwitchState.FE_SWITCH_UPDATED) {
+ allValid = false;
+ break;
+ }
}
if (! allValid)
continue;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddShortestPathFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddShortestPathFlowResource.java
deleted file mode 100644
index 4d03623..0000000
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddShortestPathFlowResource.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package net.onrc.onos.ofcontroller.flowmanager.web;
-
-import java.io.IOException;
-
-import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
-import net.onrc.onos.ofcontroller.util.FlowId;
-import net.onrc.onos.ofcontroller.util.FlowPath;
-
-import org.codehaus.jackson.JsonGenerationException;
-import org.codehaus.jackson.map.JsonMappingException;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.restlet.resource.Post;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Flow Manager REST API implementation: Add a Flow by delegating
- * the Shortest Path computation to ONOS:
- *
- * POST /wm/flow/add-shortest-path/json
- */
-public class AddShortestPathFlowResource extends ServerResource {
-
- protected final static Logger log = LoggerFactory.getLogger(AddShortestPathFlowResource.class);
-
- /**
- * Implement the API.
- *
- * @param flowJson a string with the JSON representation of the Flow to
- * add.
- * @return the Flow ID of the added flow.
- */
- @Post("json")
- public FlowId store(String flowJson) {
- FlowId result = new FlowId();
-
- IFlowService flowService =
- (IFlowService)getContext().getAttributes().
- get(IFlowService.class.getCanonicalName());
-
- if (flowService == null) {
- log.debug("ONOS Flow Service not found");
- return result;
- }
-
- //
- // Extract the arguments
- // NOTE: The "flow" is specified in JSON format.
- //
- ObjectMapper mapper = new ObjectMapper();
- String flowPathStr = flowJson;
- FlowPath flowPath = null;
- log.debug("Add Shortest Path Flow Path: " + flowPathStr);
- try {
- flowPath = mapper.readValue(flowPathStr, FlowPath.class);
- } catch (JsonGenerationException e) {
- e.printStackTrace();
- } catch (JsonMappingException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- // Process the request
- if (flowPath != null) {
- FlowId addedFlowId = flowService.addFlow(flowPath);
- if (addedFlowId != null)
- result = addedFlowId;
- }
-
- return result;
- }
-}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/FlowWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/FlowWebRoutable.java
index c358263..73a3936 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/FlowWebRoutable.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/FlowWebRoutable.java
@@ -17,7 +17,6 @@
public Restlet getRestlet(Context context) {
Router router = new Router(context);
router.attach("/add/json", AddFlowResource.class);
- router.attach("/add-shortest-path/json", AddShortestPathFlowResource.class);
router.attach("/delete/{flow-id}/json", DeleteFlowResource.class);
router.attach("/get/{flow-id}/json", GetFlowByIdResource.class);
router.attach("/getall/json", GetAllFlowsResource.class);
@@ -30,6 +29,6 @@
*/
@Override
public String basePath() {
- return "/wm/flow";
+ return "/wm/onos/flows";
}
}
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 a4f0a8c..641faaf 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
@@ -139,8 +139,8 @@
switch (msg.getType()) {
case FLOW_REMOVED:
OFFlowRemoved flowMsg = (OFFlowRemoved) msg;
- log.debug("Got flow removed from "+ sw.getId() +": "+ flowMsg.getCookie());
FlowEntryId id = new FlowEntryId(flowMsg.getCookie());
+ log.debug("Got flow entry removed from " + sw.getId() + ": " + id);
flowManager.flowEntryOnSwitchExpired(sw, id);
break;
default:
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 3f61248..6485c5e 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
@@ -735,10 +735,13 @@
}
//
- // TODO: Set the following flag
- // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
- // See method ForwardingBase::pushRoute()
+ // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
+ // permanent.
//
+ if ((flowEntry.idleTimeout() != 0) ||
+ (flowEntry.hardTimeout() != 0)) {
+ fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+ }
//
// Write the message to the switch
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/web/FlowProgrammerWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/web/FlowProgrammerWebRoutable.java
index 22450f7..9325a00 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/web/FlowProgrammerWebRoutable.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/web/FlowProgrammerWebRoutable.java
@@ -22,7 +22,7 @@
@Override
public String basePath() {
- return "/wm/fprog";
+ return "/wm/onos/flowprogrammer";
}
}
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 b062e2b..65bc40b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -7,7 +7,6 @@
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;
@@ -25,6 +24,7 @@
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
+import net.onrc.onos.ofcontroller.devicemanager.IOnosDeviceService;
import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
@@ -51,8 +51,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.ListMultimap;
import com.google.common.net.InetAddresses;
public class Forwarding implements IOFMessageListener, IFloodlightModule,
@@ -61,6 +61,8 @@
private final int IDLE_TIMEOUT = 5; // seconds
private final int HARD_TIMEOUT = 0; // seconds
+
+ private final int PATH_PUSHED_TIMEOUT = 3000; // milliseconds
private IFloodlightProviderService floodlightProvider;
private IFlowService flowService;
@@ -70,12 +72,15 @@
private IDeviceStorage deviceStorage;
private TopologyManager topologyService;
- private Map<Path, Long> pendingFlows;
- private Multimap<Long, PacketToPush> waitingPackets;
+ //private Map<Path, Long> pendingFlows;
+ // TODO it seems there is a Guava collection that will time out entries.
+ // We should see if this will work here.
+ private Map<Path, PushedFlow> pendingFlows;
+ private ListMultimap<Long, PacketToPush> waitingPackets;
private final Object lock = new Object();
- public class PacketToPush {
+ private class PacketToPush {
public final OFPacketOut packet;
public final long dpid;
@@ -85,15 +90,35 @@
}
}
- public final class Path {
+ private class PushedFlow {
+ public final long flowId;
+ private final long pushedTime;
+ public short firstHopOutPort = OFPort.OFPP_NONE.getValue();
+
+ public PushedFlow(long flowId) {
+ this.flowId = flowId;
+ pushedTime = System.currentTimeMillis();
+ }
+
+ public boolean isExpired() {
+ return (System.currentTimeMillis() - pushedTime) > PATH_PUSHED_TIMEOUT;
+ }
+ }
+
+ private final class Path {
public final SwitchPort srcPort;
public final SwitchPort dstPort;
+ public final MACAddress srcMac;
+ public final MACAddress dstMac;
- public Path(SwitchPort src, SwitchPort dst) {
+ public Path(SwitchPort src, SwitchPort dst,
+ MACAddress srcMac, MACAddress dstMac) {
srcPort = new SwitchPort(new Dpid(src.dpid().value()),
new Port(src.port().value()));
dstPort = new SwitchPort(new Dpid(dst.dpid().value()),
new Port(dst.port().value()));
+ this.srcMac = srcMac;
+ this.dstMac = dstMac;
}
@Override
@@ -104,7 +129,9 @@
Path otherPath = (Path) other;
return srcPort.equals(otherPath.srcPort) &&
- dstPort.equals(otherPath.dstPort);
+ dstPort.equals(otherPath.dstPort) &&
+ srcMac.equals(otherPath.srcMac) &&
+ dstMac.equals(otherPath.dstMac);
}
@Override
@@ -112,8 +139,16 @@
int hash = 17;
hash = 31 * hash + srcPort.hashCode();
hash = 31 * hash + dstPort.hashCode();
+ hash = 31 * hash + srcMac.hashCode();
+ hash = 31 * hash + dstMac.hashCode();
return hash;
}
+
+ @Override
+ public String toString() {
+ return "(" + srcMac + " at " + srcPort + ") => ("
+ + dstPort + " at " + dstMac + ")";
+ }
}
@Override
@@ -139,6 +174,7 @@
dependencies.add(IFloodlightProviderService.class);
dependencies.add(IFlowService.class);
dependencies.add(IFlowPusherService.class);
+ dependencies.add(IOnosDeviceService.class);
return dependencies;
}
@@ -152,10 +188,12 @@
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- pendingFlows = new ConcurrentHashMap<Path, Long>();
+ //pendingFlows = new ConcurrentHashMap<Path, Long>();
+ pendingFlows = new HashMap<Path, PushedFlow>();
//waitingPackets = Multimaps.synchronizedSetMultimap(
//HashMultimap.<Long, PacketToPush>create());
- waitingPackets = HashMultimap.create();
+ //waitingPackets = HashMultimap.create();
+ waitingPackets = LinkedListMultimap.create();
deviceStorage = new DeviceStorageImpl();
deviceStorage.init("","");
@@ -176,7 +214,8 @@
@Override
public boolean isCallbackOrderingPrereq(OFType type, String name) {
return (type == OFType.PACKET_IN) &&
- (name.equals("devicemanager") || name.equals("proxyarpmanager"));
+ (name.equals("devicemanager") || name.equals("proxyarpmanager")
+ || name.equals("onosdevicemanager"));
}
@Override
@@ -233,7 +272,8 @@
// actually ARP before broadcasting, so we can trick it into sending
// our non-ARP packets.
// TODO This should be refactored later to account for the new use case.
- datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize()));
+ datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(),
+ -1L, (short)-1, sw.getId(), pi.getInPort()));
}
private void handlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
@@ -244,13 +284,17 @@
destinationMac);
if (deviceObject == null) {
- log.debug("No device entry found for {}", destinationMac);
+ log.debug("No device entry found for {} - broadcasting packet",
+ destinationMac);
+ handleBroadcast(sw, pi, eth);
return;
}
Iterator<IPortObject> ports = deviceObject.getAttachedPorts().iterator();
if (!ports.hasNext()) {
- log.debug("No attachment point found for device {}", destinationMac);
+ log.debug("No attachment point found for device {} - broadcasting packet",
+ destinationMac);
+ handleBroadcast(sw, pi, eth);
return;
}
IPortObject portObject = ports.next();
@@ -271,20 +315,35 @@
FlowPath flowPath, reverseFlowPath;
- Path pathspec = new Path(srcSwitchPort, dstSwitchPort);
+ Path pathspec = new Path(srcSwitchPort, dstSwitchPort,
+ srcMacAddress, dstMacAddress);
// TODO check concurrency
synchronized (lock) {
- Long existingFlowId = pendingFlows.get(pathspec);
+ PushedFlow existingFlow = pendingFlows.get(pathspec);
+ //Long existingFlowId = pendingFlows.get(pathspec);
- if (existingFlowId != null) {
+ if (existingFlow != null && !existingFlow.isExpired()) {
log.debug("Found existing flow {}",
- HexString.toHexString(existingFlowId));
+ HexString.toHexString(existingFlow.flowId));
OFPacketOut po = constructPacketOut(pi, sw);
- waitingPackets.put(existingFlowId, new PacketToPush(po, sw.getId()));
+
+ if (existingFlow.firstHopOutPort != OFPort.OFPP_NONE.getValue()) {
+ // Flow has been sent to the switches so it is safe to
+ // send a packet out now
+ sendPacketOut(sw, po, existingFlow.firstHopOutPort);
+ }
+ else {
+ // Flow has not yet been sent to switches so save the
+ // packet out for later
+ waitingPackets.put(existingFlow.flowId,
+ new PacketToPush(po, sw.getId()));
+ }
return;
}
+ //log.debug("Couldn't match {} in {}", pathspec, pendingFlows);
+
log.debug("Adding new flow between {} at {} and {} at {}",
new Object[]{srcMacAddress, srcSwitchPort, dstMacAddress, dstSwitchPort});
@@ -338,11 +397,14 @@
reverseFlowPath.setFlowId(reverseFlowId);
OFPacketOut po = constructPacketOut(pi, sw);
- Path reversePathSpec = new Path(dstSwitchPort, srcSwitchPort);
+ Path reversePathSpec = new Path(dstSwitchPort, srcSwitchPort,
+ dstMacAddress, srcMacAddress);
// Add to waiting lists
- pendingFlows.put(pathspec, flowId.value());
- pendingFlows.put(reversePathSpec, reverseFlowId.value());
+ //pendingFlows.put(pathspec, flowId.value());
+ //pendingFlows.put(reversePathSpec, reverseFlowId.value());
+ pendingFlows.put(pathspec, new PushedFlow(flowId.value()));
+ pendingFlows.put(reversePathSpec, new PushedFlow(reverseFlowId.value()));
waitingPackets.put(flowId.value(), new PacketToPush(po, sw.getId()));
}
@@ -407,33 +469,44 @@
}
private void flowInstalled(FlowPath installedFlowPath) {
- // TODO check concurrency
- // will need to sync and access both collections at once.
long flowId = installedFlowPath.flowId().value();
+ short outPort =
+ installedFlowPath.flowEntries().get(0).outPort().value();
+
+ MACAddress srcMacAddress = installedFlowPath.flowEntryMatch().srcMac();
+ MACAddress dstMacAddress = installedFlowPath.flowEntryMatch().dstMac();
+
Collection<PacketToPush> packets;
synchronized (lock) {
+ log.debug("Flow {} has been installed, sending queued packets",
+ installedFlowPath.flowId());
+
packets = waitingPackets.removeAll(flowId);
- //remove pending flows entry
- Path pathToRemove = new Path(installedFlowPath.dataPath().srcPort(),
- installedFlowPath.dataPath().dstPort());
- pendingFlows.remove(pathToRemove);
-
+ // remove pending flows entry
+ Path installedPath = new Path(installedFlowPath.dataPath().srcPort(),
+ installedFlowPath.dataPath().dstPort(),
+ srcMacAddress, dstMacAddress);
+ //pendingFlows.remove(pathToRemove);
+ PushedFlow existingFlow = pendingFlows.get(installedPath);
+ if (existingFlow != null)
+ existingFlow.firstHopOutPort = outPort;
}
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);
-
- flowPusher.add(sw, po);
+ sendPacketOut(sw, packet.packet, outPort);
}
}
+
+ private void sendPacketOut(IOFSwitch sw, OFPacketOut po, short outPort) {
+ po.getActions().add(new OFActionOutput(outPort));
+ po.setActionsLength((short)
+ (po.getActionsLength() + OFActionOutput.MINIMUM_LENGTH));
+ po.setLengthU(po.getLengthU() + OFActionOutput.MINIMUM_LENGTH);
+
+ flowPusher.add(sw, po);
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java
index 8eae558..4350ba6 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java
@@ -12,6 +12,7 @@
@Override
public Router getRestlet(Context context) {
Router router = new Router(context);
+ router.attach("/links/json", LinksResource.class);
router.attach("/autoportfast/{state}/json", AutoPortFast.class); // enable/true or disable/false
return router;
}
@@ -21,6 +22,6 @@
*/
@Override
public String basePath() {
- return "/wm/linkdiscovery";
+ return "/wm/onos/linkdiscovery";
}
}
\ No newline at end of file
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 ee8f23d..44b9ea0 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
@@ -4,38 +4,40 @@
import java.net.InetAddress;
import net.floodlightcontroller.util.MACAddress;
+// TODO This is getting very messy!!! Needs refactoring
public class ArpMessage implements Serializable {
- /**
- *
- */
private static final long serialVersionUID = 1L;
private final Type type;
private final InetAddress forAddress;
private final byte[] packetData;
- //ARP reply message needs MAC info
+ // ARP reply message needs MAC info
private final MACAddress mac;
- //only send the ARP request message to the device attachment needs the attachment switch and port.
+ // Only send the ARP request message to the device attachment needs the
+ // attachment switch and port.
private final long outSwitch;
private final short outPort;
-
+ private final long inSwitch;
+ private final short inPort;
public enum Type {
REQUEST,
REPLY
}
- private ArpMessage(Type type, InetAddress address, byte[] eth) {
- // TODO Auto-generated constructor stub
+ private ArpMessage(Type type, InetAddress address, byte[] eth,
+ long outSwitch, short outPort, long inSwitch, short inPort) {
this.type = type;
this.forAddress = address;
this.packetData = eth;
this.mac = null;
this.outSwitch = -1;
this.outPort = -1;
+ this.inSwitch = inSwitch;
+ this.inPort = inPort;
}
private ArpMessage(Type type, InetAddress address) {
@@ -46,6 +48,8 @@
this.outSwitch = -1;
this.outPort = -1;
+ this.inSwitch = -1;
+ this.inPort = -1;
}
// the ARP reply message with MAC
private ArpMessage(Type type, InetAddress address, MACAddress mac) {
@@ -55,6 +59,9 @@
this.mac = mac;
this.outSwitch = -1;
this.outPort = -1;
+
+ this.inSwitch = -1;
+ this.inPort = -1;
}
// construct ARP request message with attachment switch and port
@@ -66,24 +73,32 @@
this.mac = null;
this.outSwitch = outSwitch;
this.outPort = outPort;
+
+ this.inSwitch = -1;
+ this.inPort = -1;
}
- public static ArpMessage newRequest(InetAddress forAddress, byte[] arpRequest) {
- return new ArpMessage(Type.REQUEST, forAddress, arpRequest);
+ // TODO Awful quick fix - caller has to supply dummy outSwitch and outPort
+ public static ArpMessage newRequest(InetAddress forAddress, byte[] arpRequest,
+ long outSwitch, short outPort, long inSwitch, short inPort) {
+ return new ArpMessage(Type.REQUEST, forAddress, arpRequest,
+ outSwitch, outPort, inSwitch, inPort);
}
public static ArpMessage newReply(InetAddress forAddress) {
return new ArpMessage(Type.REPLY, forAddress);
}
+
//ARP reply message with MAC
public static ArpMessage newReply(InetAddress forAddress, MACAddress mac) {
return new ArpMessage(Type.REPLY, forAddress, mac);
-
}
- //ARP reqsuest message with attachment switch and port
- public static ArpMessage newRequest(InetAddress forAddress, byte[] arpRequest, long outSwitch, short outPort ) {
- return new ArpMessage(Type.REQUEST, forAddress, arpRequest, outSwitch, outPort);
-
+
+ //ARP request message with attachment switch and port
+ public static ArpMessage newRequest(InetAddress forAddress,
+ byte[] arpRequest, long outSwitch, short outPort ) {
+ return new ArpMessage(Type.REQUEST, forAddress, arpRequest, outSwitch,
+ outPort);
}
public Type getType() {
@@ -97,6 +112,7 @@
public byte[] getPacket() {
return packetData;
}
+
public MACAddress getMAC() {
return mac;
}
@@ -108,5 +124,12 @@
public short getOutPort() {
return outPort;
}
+
+ public long getInSwitch() {
+ return inSwitch;
+ }
+ public short getInPort() {
+ return inPort;
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 5e0b752..9d9e36d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -63,7 +63,7 @@
private final long ARP_TIMER_PERIOD = 100; //ms
- private static final int ARP_REQUEST_TIMEOUT = 500; //ms
+ private static final int ARP_REQUEST_TIMEOUT = 2000; //ms
private IFloodlightProviderService floodlightProvider;
private ITopologyService topology;
@@ -77,7 +77,7 @@
private short vlan;
private static final short NO_VLAN = 0;
- private ArpCache arpCache;
+ //private ArpCache arpCache;
private SetMultimap<InetAddress, ArpRequest> arpRequests;
@@ -165,7 +165,7 @@
this.configService = context.getServiceImpl(IConfigInfoService.class);
this.restApi = context.getServiceImpl(IRestApiService.class);
- arpCache = new ArpCache();
+ //arpCache = new ArpCache();
arpRequests = Multimaps.synchronizedSetMultimap(
HashMultimap.<InetAddress, ArpRequest>create());
@@ -207,10 +207,7 @@
//Have to synchronize externally on the Multimap while using an iterator,
//even though it's a synchronizedMultimap
- synchronized (arpRequests) {
- //log.debug("Current have {} outstanding requests",
- //arpRequests.size());
-
+ synchronized (arpRequests) {
Iterator<Map.Entry<InetAddress, ArpRequest>> it
= arpRequests.entries().iterator();
@@ -222,14 +219,15 @@
log.debug("Cleaning expired ARP request for {}",
entry.getKey().getHostAddress());
- //if he ARP Request is expired and then delete the device
+ // If the ARP request is expired and then delete the device
+ // TODO check whether this is OK from this thread
IDeviceObject targetDevice =
deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(entry.getKey()));
- if(targetDevice!=null)
- {deviceStorage.removeDevice(targetDevice);
- log.debug("RemoveDevice: {} due to no have not recieve the ARP reply", targetDevice.toString());
- }
+ if (targetDevice != null) {
+ deviceStorage.removeDevice(targetDevice);
+ log.debug("RemoveDevice: {} due to no have not recieve the ARP reply", targetDevice.toString());
+ }
it.remove();
@@ -263,7 +261,7 @@
@Override
public boolean isCallbackOrderingPrereq(OFType type, String name) {
if (type == OFType.PACKET_IN) {
- return "devicemanager".equals(name);
+ return "devicemanager".equals(name) || "onosdevicemanager".equals(name);
}
else {
return false;
@@ -272,7 +270,7 @@
@Override
public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return false;
+ return type == OFType.PACKET_IN && "onosforwarding".equals(name);
}
@Override
@@ -287,17 +285,11 @@
if (eth.getEtherType() == Ethernet.TYPE_ARP){
ARP arp = (ARP) eth.getPayload();
if (arp.getOpCode() == ARP.OP_REQUEST) {
- log.debug("receive ARP request");
- //TODO check what the DeviceManager does about propagating
- //or swallowing ARPs. We want to go after DeviceManager in the
- //chain but we really need it to CONTINUE ARP packets so we can
- //get them.
handleArpRequest(sw, pi, arp, eth);
}
else if (arp.getOpCode() == ARP.OP_REPLY) {
- log.debug("receive ARP reply");
- handleArpReply(sw, pi, arp);
- sendToOtherNodesReply(eth, pi);
+ handleArpReply(sw, pi, arp);
+ sendToOtherNodesReply(eth, pi);
}
// Stop ARP packets here
@@ -337,20 +329,30 @@
}
//MACAddress macAddress = arpCache.lookup(target);
-
- IDeviceObject targetDevice =
- deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(target));
- log.debug("targetDevice: {}", targetDevice);
arpRequests.put(target, new ArpRequest(
new HostArpRequester(arp, sw.getId(), pi.getInPort()), false));
- if (targetDevice != null) {
- // Even the device in our database is not null, we do not reply to the request directly, but to check whether the device is still valid
+ IDeviceObject targetDevice =
+ deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(target));
+
+ if (targetDevice == null) {
+ if (log.isTraceEnabled()) {
+ log.trace("No device info found for {} - broadcasting",
+ target.getHostAddress());
+ }
+
+ // We don't know the device so broadcast the request out
+ sendToOtherNodes(eth, sw.getId(), pi);
+ }
+ else {
+ // Even if the device exists in our database, we do not reply to
+ // the request directly, but check whether the device is still valid
MACAddress macAddress = MACAddress.valueOf(targetDevice.getMACAddress());
if (log.isTraceEnabled()) {
- log.trace("The target Device Record in DB is: {} => {} from ARP request host at {}/{}", new Object [] {
+ log.trace("The target Device Record in DB is: {} => {} from ARP request host at {}/{}",
+ new Object [] {
inetAddressToString(arp.getTargetProtocolAddress()),
macAddress.toString(),
HexString.toHexString(sw.getId()), pi.getInPort()});
@@ -359,41 +361,38 @@
// sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
log.trace("Checking the device info from DB is still valid or not");
- Iterable<IPortObject> outPorts=targetDevice.getAttachedPorts();
+ Iterable<IPortObject> outPorts = targetDevice.getAttachedPorts();
- if(!outPorts.iterator().hasNext()){
- log.debug("outPort : null");
- sendToOtherNodes(eth, pi);
- }else{
-
+ if (!outPorts.iterator().hasNext()){
+ if (log.isTraceEnabled()) {
+ log.trace("Device {} exists but is not connected to any ports" +
+ " - broadcasting", macAddress);
+ }
+
+ sendToOtherNodes(eth, sw.getId(), pi);
+ }
+ else {
for (IPortObject portObject : outPorts) {
- long outSwitch=0;
- short outPort=0;
-
+ long outSwitch = 0;
+ short outPort = 0;
if (!portObject.getLinkedPorts().iterator().hasNext()) {
- outPort=portObject.getNumber();
- log.debug("outPort:{} ", outPort);
- }
-
- Iterable<ISwitchObject> outSwitches= targetDevice.getSwitch();
-
- for (ISwitchObject outswitch : outSwitches) {
-
- outSwitch= HexString.toLong(outswitch.getDPID());
- log.debug("outSwitch.DPID:{}; outPort: {}", outswitch.getDPID(), outPort );
- sendToOtherNodes( eth, pi, outSwitch, outPort);
+ outPort = portObject.getNumber();
}
+
+ ISwitchObject outSwitchObject = portObject.getSwitch();
+ outSwitch = HexString.toLong(outSwitchObject.getDPID());
+
+ if (log.isTraceEnabled()) {
+ log.trace("Probing device {} on port {}/{}",
+ new Object[] {macAddress,
+ HexString.toHexString(outSwitch), outPort});
+ }
+
+ sendToOtherNodes(eth, pi, outSwitch, outPort);
}
}
-
- }else {
- log.debug("The Device info in DB is {} for IP {}", targetDevice, inetAddressToString(arp.getTargetProtocolAddress()));
-
- // We don't know the device so broadcast the request out
- sendToOtherNodes(eth, pi);
}
-
}
private void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp){
@@ -516,7 +515,7 @@
}
}
- private void sendToOtherNodes(Ethernet eth, OFPacketIn pi) {
+ private void sendToOtherNodes(Ethernet eth, long inSwitchId, OFPacketIn pi) {
ARP arp = (ARP) eth.getPayload();
if (log.isTraceEnabled()) {
@@ -532,24 +531,25 @@
return;
}
- datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize()));
+ datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(),
+ -1L, (short)-1, inSwitchId, pi.getInPort()));
}
+
//hazelcast to other ONOS instances to send the ARP packet out on outPort of outSwitch
private void sendToOtherNodes(Ethernet eth, OFPacketIn pi, long outSwitch, short outPort) {
ARP arp = (ARP) eth.getPayload();
if (log.isTraceEnabled()) {
- log.trace("Sending ARP request for {} to other ONOS instances with outSwitch {} ",
- inetAddressToString(arp.getTargetProtocolAddress()), String.valueOf(outSwitch));
-
+ log.trace("Sending ARP request for {} to other ONOS instances with outSwitch {} ",
+ inetAddressToString(arp.getTargetProtocolAddress()), String.valueOf(outSwitch));
}
InetAddress targetAddress;
try {
- targetAddress = InetAddress.getByAddress(arp.getTargetProtocolAddress());
+ targetAddress = InetAddress.getByAddress(arp.getTargetProtocolAddress());
} catch (UnknownHostException e) {
- log.error("Unknown host", e);
- return;
+ log.error("Unknown host", e);
+ return;
}
datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(), outSwitch, outPort));
@@ -557,25 +557,26 @@
}
+
private void sendToOtherNodesReply(Ethernet eth, OFPacketIn pi) {
ARP arp = (ARP) eth.getPayload();
if (log.isTraceEnabled()) {
- log.trace("Sending ARP reply for {} to other ONOS instances",
- inetAddressToString(arp.getSenderProtocolAddress()));
+ log.trace("Sending ARP reply for {} to other ONOS instances",
+ inetAddressToString(arp.getSenderProtocolAddress()));
}
InetAddress targetAddress;
MACAddress mac = new MACAddress(arp.getSenderHardwareAddress());
try {
- targetAddress = InetAddress.getByAddress(arp.getSenderProtocolAddress());
+ targetAddress = InetAddress.getByAddress(arp.getSenderProtocolAddress());
} catch (UnknownHostException e) {
- log.error("Unknown host", e);
- return;
+ log.error("Unknown host", e);
+ return;
}
- datagrid.sendArpRequest(ArpMessage.newReply(targetAddress,mac));
+ datagrid.sendArpRequest(ArpMessage.newReply(targetAddress, mac));
//datagrid.sendArpReply(ArpMessage.newRequest(targetAddress, eth.serialize()));
}
@@ -628,7 +629,8 @@
}
}
- private void broadcastArpRequestOutMyEdge(byte[] arpRequest) {
+ private void broadcastArpRequestOutMyEdge(byte[] arpRequest,
+ long inSwitch, short inPort) {
List<SwitchPort> switchPorts = new ArrayList<SwitchPort>();
for (IOFSwitch sw : floodlightProvider.getSwitches().values()) {
@@ -648,9 +650,17 @@
for (IPortObject portObject : ports) {
if (!portObject.getLinkedPorts().iterator().hasNext()) {
+ short portNumber = portObject.getNumber();
+
+ if (sw.getId() == inSwitch && portNumber == inPort) {
+ // This is the port that the ARP message came in,
+ // so don't broadcast out this port
+ continue;
+ }
+
switchPorts.add(new SwitchPort(new Dpid(sw.getId()),
- new Port(portObject.getNumber())));
- actions.add(new OFActionOutput(portObject.getNumber()));
+ new Port(portNumber)));
+ actions.add(new OFActionOutput(portNumber));
}
}
@@ -669,7 +679,9 @@
}
}
- log.debug("Broadcast ARP request to: {}", switchPorts);
+ if (log.isTraceEnabled()) {
+ log.trace("Broadcast ARP request to: {}", switchPorts);
+ }
}
private void sendArpRequestOutPort(byte[] arpRequest, long dpid, short port) {
@@ -784,7 +796,8 @@
@Override
public MACAddress getMacAddress(InetAddress ipAddress) {
- return arpCache.lookup(ipAddress);
+ //return arpCache.lookup(ipAddress);
+ return null;
}
@Override
@@ -800,7 +813,8 @@
@Override
public List<String> getMappings() {
- return arpCache.getMappings();
+ //return arpCache.getMappings();
+ return new ArrayList<String>();
}
/*
@@ -814,7 +828,8 @@
switch (arpMessage.getType()){
case REQUEST:
if(arpMessage.getOutSwitch() == -1 || arpMessage.getOutPort() == -1){
- broadcastArpRequestOutMyEdge(arpMessage.getPacket());
+ broadcastArpRequestOutMyEdge(arpMessage.getPacket(),
+ arpMessage.getInSwitch(), arpMessage.getInPort());
}else{
sendArpRequestOutPort(arpMessage.getPacket(),arpMessage.getOutSwitch(),arpMessage.getOutPort());
log.debug("OutSwitch in ARP request message is: {}; OutPort in ARP request message is: {}",arpMessage.getOutSwitch(),arpMessage.getOutPort());
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java b/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
index a4a2be3..d9e1314 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
@@ -69,8 +69,11 @@
//
// Test whether we are computing a path from/to the same DPID.
// If "yes", then just add a single flow entry in the return result.
+ // However, if the "in" and "out" ports are same, return null.
//
if (dpid_src.equals(dpid_dest)) {
+ if (src.port().value() == dest.port().value())
+ return null; // "In" and "Out" ports are same
FlowEntry flowEntry = new FlowEntry();
flowEntry.setDpid(src.dpid());
flowEntry.setInPort(src.port());
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 6b2ab99..570e94f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -10,12 +10,13 @@
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
-
+import net.floodlightcontroller.restserver.IRestApiService;
import net.onrc.onos.datagrid.IDatagridService;
import net.onrc.onos.graph.DBOperation;
import net.onrc.onos.graph.GraphDBManager;
import net.onrc.onos.graph.GraphDBOperation;
import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
+import net.onrc.onos.ofcontroller.topology.web.OnosTopologyWebRoutable;
import net.onrc.onos.ofcontroller.util.DataPath;
import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowPath;
@@ -40,6 +41,7 @@
protected static final String GraphDBStore = "graph_db_store";
protected DBOperation dbHandler;
+ protected IRestApiService restApi;
/**
@@ -154,6 +156,7 @@
public void init(FloodlightModuleContext context)
throws FloodlightModuleException {
floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+ restApi = context.getServiceImpl(IRestApiService.class);
Map<String, String> configMap = context.getConfigParams(this);
String conf = configMap.get(DBConfigFile);
String dbStore = configMap.get(GraphDBStore);
@@ -167,6 +170,7 @@
*/
@Override
public void startUp(FloodlightModuleContext context) {
+ restApi.addRestletRoutable(new OnosTopologyWebRoutable());
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/web/OnosTopologyWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/topology/web/OnosTopologyWebRoutable.java
new file mode 100644
index 0000000..90eed9a
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/web/OnosTopologyWebRoutable.java
@@ -0,0 +1,29 @@
+package net.onrc.onos.ofcontroller.topology.web;
+
+import org.restlet.Context;
+import org.restlet.Restlet;
+import org.restlet.routing.Router;
+
+import net.floodlightcontroller.restserver.RestletRoutable;
+import net.onrc.onos.graph.web.TopoDevicesResource;
+import net.onrc.onos.ofcontroller.core.web.TopoLinksResource;
+import net.onrc.onos.ofcontroller.core.web.TopoSwitchesResource;
+
+public class OnosTopologyWebRoutable implements RestletRoutable {
+
+ @Override
+ public Restlet getRestlet(Context context) {
+ Router router = new Router(context);
+ router.attach("/route/{src-dpid}/{src-port}/{dst-dpid}/{dst-port}/json", RouteResource.class);
+ router.attach("/switches/{filter}/json", TopoSwitchesResource.class);
+ router.attach("/links/json", TopoLinksResource.class);
+ router.attach("/devices/json", TopoDevicesResource.class);
+ return router;
+ }
+
+ @Override
+ public String basePath() {
+ return "/wm/onos/topology";
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
index b6d980a..82af20c 100644
--- a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
@@ -11,6 +11,7 @@
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.restserver.IRestApiService;
+import net.onrc.onos.registry.controller.web.RegistryWebRoutable;
import org.openflow.util.HexString;
import org.slf4j.Logger;
diff --git a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
index 50ee137..b03aea2 100644
--- a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
@@ -15,6 +15,7 @@
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.restserver.IRestApiService;
+import net.onrc.onos.registry.controller.web.RegistryWebRoutable;
import org.openflow.util.HexString;
import org.slf4j.Logger;
diff --git a/src/main/java/net/onrc/onos/registry/controller/ControllerRegistryResource.java b/src/main/java/net/onrc/onos/registry/controller/web/ControllerRegistryResource.java
similarity index 83%
rename from src/main/java/net/onrc/onos/registry/controller/ControllerRegistryResource.java
rename to src/main/java/net/onrc/onos/registry/controller/web/ControllerRegistryResource.java
index 8660688..676bcb3 100644
--- a/src/main/java/net/onrc/onos/registry/controller/ControllerRegistryResource.java
+++ b/src/main/java/net/onrc/onos/registry/controller/web/ControllerRegistryResource.java
@@ -1,8 +1,11 @@
-package net.onrc.onos.registry.controller;
+package net.onrc.onos.registry.controller.web;
import java.util.ArrayList;
import java.util.Collection;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.RegistryException;
+
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
diff --git a/src/main/java/net/onrc/onos/registry/controller/RegistryWebRoutable.java b/src/main/java/net/onrc/onos/registry/controller/web/RegistryWebRoutable.java
similarity index 86%
rename from src/main/java/net/onrc/onos/registry/controller/RegistryWebRoutable.java
rename to src/main/java/net/onrc/onos/registry/controller/web/RegistryWebRoutable.java
index 74dede4..77dd72d 100644
--- a/src/main/java/net/onrc/onos/registry/controller/RegistryWebRoutable.java
+++ b/src/main/java/net/onrc/onos/registry/controller/web/RegistryWebRoutable.java
@@ -1,4 +1,4 @@
-package net.onrc.onos.registry.controller;
+package net.onrc.onos.registry.controller.web;
import net.floodlightcontroller.restserver.RestletRoutable;
@@ -18,7 +18,7 @@
@Override
public String basePath() {
- return "/wm/registry";
+ return "/wm/onos/registry";
}
}
diff --git a/src/main/java/net/onrc/onos/registry/controller/SwitchRegistryResource.java b/src/main/java/net/onrc/onos/registry/controller/web/SwitchRegistryResource.java
similarity index 79%
rename from src/main/java/net/onrc/onos/registry/controller/SwitchRegistryResource.java
rename to src/main/java/net/onrc/onos/registry/controller/web/SwitchRegistryResource.java
index 599a1af..21b0c09 100644
--- a/src/main/java/net/onrc/onos/registry/controller/SwitchRegistryResource.java
+++ b/src/main/java/net/onrc/onos/registry/controller/web/SwitchRegistryResource.java
@@ -1,9 +1,12 @@
-package net.onrc.onos.registry.controller;
+package net.onrc.onos.registry.controller.web;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import net.onrc.onos.registry.controller.ControllerRegistryEntry;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
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 a842665..dfd31ab 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
@@ -1,6 +1,5 @@
net.floodlightcontroller.core.FloodlightProvider
net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher
-net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl
net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager
net.floodlightcontroller.topology.TopologyManager
net.floodlightcontroller.forwarding.Forwarding
@@ -21,3 +20,4 @@
net.onrc.onos.ofcontroller.forwarding.Forwarding
net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager
net.onrc.onos.ofcontroller.core.config.DefaultConfiguration
+net.onrc.onos.ofcontroller.devicemanager.OnosDeviceManager
diff --git a/start-onos.sh b/start-onos.sh
index 1f67368..a9d4d64 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -1,21 +1,21 @@
#!/bin/bash
# Set paths
-if [ -z "${ONOS_HOME}" ]; then
- ONOS_HOME=`dirname $0`
-fi
+ONOS_HOME="${ONOS_HOME:-`dirname $0`}"
## 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_LOGBACK=${ONOS_LOGBACK:-${ONOS_HOME}/logback.`hostname`.xml}
+LOGDIR=${ONOS_LOGDIR:-${ONOS_HOME}/onos-logs}
+
ONOS_LOG="${LOGDIR}/onos.`hostname`.log"
PCAP_LOG="${LOGDIR}/onos.`hostname`.pcap"
LOGS="$ONOS_LOG $PCAP_LOG"
+ONOS_PROPS=${ONOS_PROPS:-${ONOS_HOME}/conf/onos.properties}
+JMX_PORT=${JMX_PORT:-7189}
+
# Set JVM options
-JVM_OPTS=""
+JVM_OPTS="${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"
@@ -31,7 +31,7 @@
-XX:+UseThreadPriorities \
-XX:ThreadPriorityPolicy=42 \
-XX:+UseCompressedOops \
- -Dcom.sun.management.jmxremote.port=7189 \
+ -Dcom.sun.management.jmxremote.port=$JMX_PORT \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false"
JVM_OPTS="$JVM_OPTS -Dhazelcast.logging.type=slf4j"
@@ -39,9 +39,7 @@
# Set ONOS core main class
MAIN_CLASS="net.onrc.onos.ofcontroller.core.Main"
-if [ -z "${MVN}" ]; then
- MVN="mvn -o"
-fi
+MVN=${MVN:-mvn -o}
#<logger name="net.floodlightcontroller.linkdiscovery.internal" level="TRACE"/>
#<appender-ref ref="STDOUT" />
@@ -101,15 +99,15 @@
# Run ONOS
echo "Starting ONOS controller ..."
- echo
+ echo
- # XXX : MVN has to run at the project top dir
+ # 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\""
+ pwd
+ echo "${MVN} exec:exec -Dexec.executable=\"java\" -Dexec.args=\"${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_PROPS}\""
- ${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 &
+ ${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_PROPS}" > ${LOGDIR}/onos.`hostname`.stdout 2>${LOGDIR}/onos.`hostname`.stderr &
echo "Waiting for ONOS to start..."
COUNT=0
@@ -160,14 +158,18 @@
case "$1" in
start)
stop
-# check_db
- start
+ check_db
+ start
+ ;;
+ startnokill)
+ check_db
+ start
;;
startifdown)
n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
if [ $n == 0 ]; then
start
- else
+ else
echo "$n instance of onos running"
fi
;;
diff --git a/vm-utils/onos.py b/vm-utils/onos.py
new file mode 100755
index 0000000..8283a66
--- /dev/null
+++ b/vm-utils/onos.py
@@ -0,0 +1,318 @@
+#!/usr/bin/env python
+
+"""
+onos.py: A basic (?) ONOS Controller() subclass for Mininet
+
+We implement the following classes:
+
+ONOSController: a custom Controller() subclass to start ONOS
+OVSSwitchONOS: a custom OVSSwitch() switch that connects to multiple controllers.
+
+We use single Zookeeper and Cassandra instances for now.
+
+As a custom file, exports:
+
+--controller onos
+--switch ovso
+
+Usage:
+
+$ sudo ./onos.py
+
+This will start up a simple 2-host, 2 ONOS network
+
+$ sudo mn --custom onos.py --controller onos,2 --switch ovso
+"""
+
+from mininet.node import Controller, OVSSwitch
+from mininet.net import Mininet
+from mininet.cli import CLI
+from mininet.topo import LinearTopo
+from mininet.log import setLogLevel, info, warn
+from mininet.util import quietRun
+
+# This should be cleaned up to avoid interfering with mn
+from shutil import copyfile
+from os import environ
+from functools import partial
+import time
+from sys import argv
+
+class ONOS( Controller ):
+ "Custom controller class for ONOS"
+
+ # Directories and configuration templates
+ home = environ[ 'HOME' ]
+ onosDir = home + "/ONOS"
+ zookeeperDir = home + "/zookeeper-3.4.5"
+ dirBase = '/tmp'
+ logDir = dirBase + '/onos-%s.logs'
+ # cassDir = dirBase + '/onos-%s.cassandra'
+ configFile = dirBase + '/onos-%s.properties'
+ logbackFile = dirBase + '/onos-%s.logback.xml'
+
+ # Base ONOS modules
+ baseModules = (
+ 'net.floodlightcontroller.core.FloodlightProvider',
+ 'net.floodlightcontroller.threadpool.ThreadPool',
+ 'net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher',
+ 'net.floodlightcontroller.ui.web.StaticWebRoutable',
+ 'net.onrc.onos.datagrid.HazelcastDatagrid',
+ 'net.onrc.onos.ofcontroller.flowmanager.FlowManager',
+ 'net.onrc.onos.ofcontroller.flowprogrammer.FlowProgrammer',
+ 'net.onrc.onos.ofcontroller.topology.TopologyManager',
+ 'net.onrc.onos.registry.controller.ZookeeperRegistry'
+ )
+
+ # Additions for reactive forwarding
+ reactiveModules = (
+ 'net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager',
+ 'net.onrc.onos.ofcontroller.core.config.DefaultConfiguration',
+ 'net.onrc.onos.ofcontroller.forwarding.Forwarding'
+ )
+
+ # Module parameters
+ ofbase = 6633
+ restbase = 8080
+ jmxbase = 7189
+
+ fc = 'net.floodlightcontroller.'
+
+ perNodeConfigBase = {
+ fc + 'core.FloodlightProvider.openflowport': ofbase,
+ fc + 'restserver.RestApiServer.port': restbase,
+ fc + 'core.FloodlightProvider.controllerid': 0
+ }
+
+ staticConfig = {
+ 'net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf':
+ '/tmp/cassandra.titan',
+ 'net.onrc.onos.datagrid.HazelcastDatagrid.datagridConfig':
+ onosDir + '/conf/hazelcast.xml',
+ 'net.floodlightcontroller.core.FloodlightProvider.workerthreads': 16,
+ 'net.floodlightcontroller.forwarding.Forwarding.idletimeout': 5,
+ 'net.floodlightcontroller.forwarding.Forwarding.hardtimeout': 0
+ }
+
+ proctag = 'mn-onos-id'
+
+ # For maven debugging
+ # mvn = 'mvn -o -e -X'
+
+ def __init__( self, name, n=1, reactive=True, runAsRoot=False, **params):
+ """n: number of ONOS instances to run (1)
+ reactive: run in reactive mode (True)
+ runAsRoot: run ONOS as root (False)"""
+ self.check()
+ self.count = n
+ self.reactive = reactive
+ self.runAsRoot = runAsRoot
+ self.ids = range( 0, self.count )
+ Controller.__init__( self, name, **params )
+ # We don't need to run as root, and it can interfere
+ # with starting Zookeeper manually
+ self.user = None
+ if not self.runAsRoot:
+ try:
+ self.user = quietRun( 'who am i' ).split()[ 0 ]
+ self.sendCmd( 'su', self.user )
+ self.waiting = False
+ except:
+ warn( '__init__: failed to drop privileges\n' )
+ # Need to run commands from ONOS dir
+ self.cmd( 'cd', self.onosDir )
+ self.cmd( 'export PATH=$PATH:%s' % self.onosDir )
+ if hasattr( self, 'mvn' ):
+ self.cmd( 'export MVN="%s"' % self.mvn )
+
+ def check( self ):
+ "Check for ONOS prerequisites"
+ if not quietRun( 'which java' ):
+ raise Exception( 'java not found -'
+ ' make sure it is installed and in $PATH' )
+ if not quietRun( 'which mvn' ):
+ raise Exception( 'Maven (mvn) not found -'
+ ' make sure it is installed and in $PATH' )
+
+
+ def waitNetstat( self, pid ):
+ """Wait for pid to show up in netstat
+ We assume that once a process is listening on some
+ port, it is ready to go!"""
+ while True:
+ output = self.cmd( 'sudo netstat -natp | grep %s/' % pid )
+ if output:
+ return output
+ info( '.' )
+ time.sleep( 1 )
+
+ def waitStart( self, procname, pattern ):
+ "Wait for at least one of procname to show up in netstat"
+ info( '* Waiting for %s startup' % procname )
+ result = self.cmd( 'pgrep -f %s' % pattern ).split()[ 0 ]
+ pid = int( result )
+ output = self.waitNetstat( pid )
+ info( '\n* %s process %d is listening\n' % ( procname, pid ) )
+ info( output )
+
+ def startCassandra( self ):
+ "Start Cassandra"
+ self.cmd( 'start-cassandra.sh start' )
+ self.waitStart( 'Cassandra', 'apache-cassandra' )
+ status = self.cmd( 'start-cassandra.sh status' )
+ if 'running' not in status:
+ raise Exception( 'Cassandra startup failed: ' + status )
+
+ def stopCassandra( self ):
+ "Stop Cassandra"
+ self.cmd( 'start-cassandra.sh stop' )
+
+ def startZookeeper( self, initcfg=True ):
+ "Start Zookeeper"
+ # Reinitialize configuration file
+ if initcfg:
+ cfg = self.zookeeperDir + '/conf/zoo.cfg'
+ template = self.zookeeperDir + '/conf/zoo_sample.cfg'
+ copyfile( template, cfg )
+ self.cmd( 'start-zk.sh restart' )
+ self.waitStart( 'Zookeeper', 'zookeeper' )
+ status = self.cmd( 'start-zk.sh status' )
+ if 'Error' in status:
+ raise Exception( 'Zookeeper startup failed: ' + status )
+
+ def stopZookeeper( self ):
+ "Stop Zookeeper"
+ self.cmd( 'start-zk.sh stop' )
+
+ def genProperties( self, id, path='/tmp' ):
+ "Generate ONOS properties file"
+ filename = path + '/onos-%s.properties' % id
+ with open( filename, 'w' ) as f:
+ # Write modules list
+ modules = list( self.baseModules )
+ if self.reactive:
+ modules += list( self.reactiveModules )
+ f.write( 'floodlight.modules = %s\n' %
+ ',\\\n'.join( modules ) )
+ # Write other parameters
+ for var, val in self.perNodeConfigBase.iteritems():
+ if type( val ) is int:
+ val += id
+ f.write( '%s = %s\n' % ( var, val ) )
+ for var, val in self.staticConfig.iteritems():
+ f.write( '%s = %s\n' % ( var, val ) )
+ return filename
+
+ def setVars( self, id, propsFile ):
+ """Set and return environment vars
+ id: ONOS instance number
+ propsFile: properties file name"""
+ # ONOS directories and files
+ logdir = self.logDir % id
+ # cassdir = self.cassDir % id
+ logback = self.logbackFile % id
+ jmxport = self.jmxbase + id
+ self.cmd( 'mkdir -p', logdir ) # , cassdir
+ self.cmd( 'export ONOS_LOGDIR="%s"' % logdir )
+ self.cmd( 'export ZOO_LOG_DIR="%s"' % logdir )
+ # self.cmd( 'export CASS_DIR="%s"' % cassdir )
+ self.cmd( 'export ONOS_LOGBACK="%s"' % logback )
+ self.cmd( 'export JMX_PORT=%s' % jmxport )
+ self.cmd( 'export JVM_OPTS="-D%s=%s"' % (
+ self.proctag, id ) )
+ self.cmd( 'export ONOS_PROPS="%s"' % propsFile )
+
+ def startONOS( self, id ):
+ """Start ONOS
+ id: new instance number"""
+ start = time.time()
+ self.stopONOS( id )
+ propsFile = self.genProperties( id )
+ self.setVars( id, propsFile )
+ self.cmdPrint( 'start-onos.sh startnokill' )
+ # start-onos.sh waits for ONOS startup
+ elapsed = time.time() - start
+ info( '* ONOS %s started in %.2f seconds\n' % ( id, elapsed ) )
+
+ def stopONOS( self, id ):
+ """Shut down ONOS
+ id: identifier for instance"""
+ pid = self.cmd( "jps -v | grep %s=%s | awk '{print $1}'" %
+ ( self.proctag, id ) ).strip()
+ if pid:
+ self.cmdPrint( 'kill', pid )
+
+ def start( self, *args ):
+ "Start ONOS instances"
+ info( '* Starting Cassandra\n' )
+ self.startCassandra()
+ info( '* Starting Zookeeper\n' )
+ self.startZookeeper()
+ for id in self.ids:
+ info( '* Starting ONOS %s\n' % id )
+ self.startONOS( id )
+
+ def stop( self, *args ):
+ "Stop ONOS instances"
+ for id in self.ids:
+ info( '* Stopping ONOS %s\n' % id )
+ self.stopONOS( id )
+ info( '* Stopping Zookeeper\n' )
+ self.stopZookeeper()
+ info( '* Stopping Cassandra\n' )
+ self.stopCassandra()
+
+ def clist( self ):
+ "Return list of controller specifiers (proto:ip:port)"
+ return [ 'tcp:127.0.0.1:%s' % ( self.ofbase + id )
+ for id in range( 0, self.count ) ]
+
+
+class OVSSwitchONOS( OVSSwitch ):
+ "OVS switch which connects to multiple controllers"
+ def start( self, controllers ):
+ OVSSwitch.start( self, controllers )
+ assert len( controllers ) == 1
+ c0 = controllers[ 0 ]
+ assert type( c0 ) == ONOS
+ clist = ','.join( c0.clist() )
+ self.cmd( 'ovs-vsctl set-controller', self, clist)
+ # Reconnect quickly to controllers (1s vs. 15s max_backoff)
+ for uuid in self.controllerUUIDs():
+ if uuid.count( '-' ) != 4:
+ # Doesn't look like a UUID
+ continue
+ uuid = uuid.strip()
+ self.cmd( 'ovs-vsctl set Controller', uuid,
+ 'max_backoff=1000' )
+
+
+def waitConnected( switches ):
+ "Wait until all switches connect to controllers"
+ start = time.time()
+ info( '* Waiting for switches to connect...\n' )
+ for s in switches:
+ info( s )
+ while not s.connected():
+ info( '.' )
+ time.sleep( 1 )
+ info( ' ' )
+ elapsed = time.time() - start
+ info( '\n* Connected in %.2f seconds\n' % elapsed )
+
+
+controllers = { 'onos': ONOS }
+switches = { 'ovso': OVSSwitchONOS }
+
+
+if __name__ == '__main__':
+ # Simple test for ONOS() controller class
+ setLogLevel( 'info' )
+ size = 2 if len( argv ) != 2 else int( argv[ 1 ] )
+ net = Mininet( topo=LinearTopo( size ),
+ controller=partial( ONOS, n=2 ),
+ switch=OVSSwitchONOS )
+ net.start()
+ waitConnected( net.switches )
+ CLI( net )
+ net.stop()
diff --git a/web/add_flow.py b/web/add_flow.py
index 9690024..6ff250a 100755
--- a/web/add_flow.py
+++ b/web/add_flow.py
@@ -14,7 +14,7 @@
from flask import Flask, json, Response, render_template, make_response, request
#
-# curl http://127.0.0.1:8080/wm/topology/route/00:00:00:00:00:00:0a:01/1/00:00:00:00:00:00:0a:04/1/json
+# curl http://127.0.0.1:8080/wm/onos/topology/route/00:00:00:00:00:00:0a:01/1/00:00:00:00:00:00:0a:04/1/json
#
## Global Var ##
@@ -37,14 +37,14 @@
if DEBUG:
print '%s' % (txt)
-# @app.route("/wm/topology/route/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
+# @app.route("/wm/onos/topology/route/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
#
# Sample output:
# {'dstPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:02'}}, 'srcPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:01'}}, 'flowEntries': [{'outPort': {'value': 1}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 0}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:01'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}, {'outPort': {'value': 0}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 9}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:02'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}]}
#
def shortest_path(v1, p1, v2, p2):
try:
- command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (ControllerIP, ControllerPort, v1, p1, v2, p2)
+ command = "curl -s http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (ControllerIP, ControllerPort, v1, p1, v2, p2)
debug("shortest_path %s" % command)
parsedResult = []
@@ -82,7 +82,7 @@
flow_path_json = json.dumps(flow_path)
try:
- command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/flow/add/json" % (flow_path_json, ControllerIP, ControllerPort)
+ command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/onos/flows/add/json" % (flow_path_json, ControllerIP, ControllerPort)
debug("add_flow_path %s" % command)
result = os.popen(command).read()
debug("result %s" % result)
@@ -96,7 +96,7 @@
flow_path_json = json.dumps(flow_path)
try:
- command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/flow/add-shortest-path/json" % (flow_path_json, ControllerIP, ControllerPort)
+ command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/onos/flows/add/json" % (flow_path_json, ControllerIP, ControllerPort)
debug("add_shortest_path_flow %s" % command)
result = os.popen(command).read()
debug("result %s" % result)
@@ -107,7 +107,7 @@
exit(1)
def delete_flow_path(flow_id):
- command = "curl -s \"http://%s:%s/wm/flow/delete/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
+ command = "curl -s \"http://%s:%s/wm/onos/flows/delete/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
debug("delete_flow_path %s" % command)
result = os.popen(command).read()
debug("result %s" % result)
diff --git a/web/clear_core.py b/web/clear_core.py
index ea3e964..36eadd6 100755
--- a/web/clear_core.py
+++ b/web/clear_core.py
@@ -23,7 +23,7 @@
try:
sw_list = json.dumps(core_switches)
- command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/core/clearflowtable/json" % (sw_list, controllers[0], onos_rest_port)
+ command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/onos/internal/clearflowtable/json" % (sw_list, controllers[0], onos_rest_port)
print command
result = os.popen(command).read()
diff --git a/web/delete_flow.py b/web/delete_flow.py
index fff9319..d38e915 100755
--- a/web/delete_flow.py
+++ b/web/delete_flow.py
@@ -14,7 +14,7 @@
#
# TODO: remove this! We don't use JSON argument here!
-# curl http://127.0.0.1:8080/wm/flow/delete/{"value":"0xf"}/json'
+# curl http://127.0.0.1:8080/wm/onos/flows/delete/{"value":"0xf"}/json'
#
## Global Var ##
@@ -34,9 +34,9 @@
if DEBUG:
print '%s' % (txt)
-# @app.route("/wm/flow/delete/<flow-id>/json")
+# @app.route("/wm/onos/flows/delete/<flow-id>/json")
def delete_flow_path(flow_id):
- command = "curl -s \"http://%s:%s/wm/flow/delete/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
+ command = "curl -s \"http://%s:%s/wm/onos/flows/delete/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
debug("delete_flow_path %s" % command)
result = os.popen(command).read()
debug("result %s" % result)
diff --git a/web/css/bootstrap.css b/web/floodlight/css/bootstrap.css
similarity index 100%
rename from web/css/bootstrap.css
rename to web/floodlight/css/bootstrap.css
diff --git a/web/css/styles.css b/web/floodlight/css/styles.css
similarity index 100%
rename from web/css/styles.css
rename to web/floodlight/css/styles.css
diff --git a/web/img/floodlight.png b/web/floodlight/img/floodlight.png
similarity index 100%
rename from web/img/floodlight.png
rename to web/floodlight/img/floodlight.png
Binary files differ
diff --git a/web/img/glyphicons-halflings-white.png b/web/floodlight/img/glyphicons-halflings-white.png
similarity index 100%
rename from web/img/glyphicons-halflings-white.png
rename to web/floodlight/img/glyphicons-halflings-white.png
Binary files differ
diff --git a/web/img/glyphicons-halflings.png b/web/floodlight/img/glyphicons-halflings.png
similarity index 100%
rename from web/img/glyphicons-halflings.png
rename to web/floodlight/img/glyphicons-halflings.png
Binary files differ
diff --git a/web/img/logo.jpg b/web/floodlight/img/logo.jpg
similarity index 100%
rename from web/img/logo.jpg
rename to web/floodlight/img/logo.jpg
Binary files differ
diff --git a/web/img/openflow-logo-40px.png b/web/floodlight/img/openflow-logo-40px.png
similarity index 100%
rename from web/img/openflow-logo-40px.png
rename to web/floodlight/img/openflow-logo-40px.png
Binary files differ
diff --git a/web/img/server.png b/web/floodlight/img/server.png
similarity index 100%
rename from web/img/server.png
rename to web/floodlight/img/server.png
Binary files differ
diff --git a/web/img/switch.png b/web/floodlight/img/switch.png
similarity index 100%
rename from web/img/switch.png
rename to web/floodlight/img/switch.png
Binary files differ
diff --git a/web/index.html b/web/floodlight/index.html
similarity index 100%
rename from web/index.html
rename to web/floodlight/index.html
diff --git a/web/js/controller-status.js b/web/floodlight/js/controller-status.js
similarity index 100%
rename from web/js/controller-status.js
rename to web/floodlight/js/controller-status.js
diff --git a/web/js/jquery-1.7.2.min.js b/web/floodlight/js/jquery-1.7.2.min.js
similarity index 100%
rename from web/js/jquery-1.7.2.min.js
rename to web/floodlight/js/jquery-1.7.2.min.js
diff --git a/web/js/main.js b/web/floodlight/js/main.js
similarity index 100%
rename from web/js/main.js
rename to web/floodlight/js/main.js
diff --git a/web/js/models/flowmodel.js b/web/floodlight/js/models/flowmodel.js
similarity index 100%
rename from web/js/models/flowmodel.js
rename to web/floodlight/js/models/flowmodel.js
diff --git a/web/js/models/hostmodel.js b/web/floodlight/js/models/hostmodel.js
similarity index 97%
rename from web/js/models/hostmodel.js
rename to web/floodlight/js/models/hostmodel.js
index 8de3dd6..1caff6c 100644
--- a/web/js/models/hostmodel.js
+++ b/web/floodlight/js/models/hostmodel.js
@@ -35,7 +35,7 @@
var self = this;
//console.log("fetching host list")
$.ajax({
- url:hackBase + "/wm/device/",
+ url:hackBase + "/wm/floodlight/device/",
dataType:"json",
success:function (data) {
//console.log("fetched host list: " + data.length);
diff --git a/web/js/models/portmodel.js b/web/floodlight/js/models/portmodel.js
similarity index 100%
rename from web/js/models/portmodel.js
rename to web/floodlight/js/models/portmodel.js
diff --git a/web/js/models/statusmodel.js b/web/floodlight/js/models/statusmodel.js
similarity index 89%
rename from web/js/models/statusmodel.js
rename to web/floodlight/js/models/statusmodel.js
index b7cdebd..5cbb526 100644
--- a/web/js/models/statusmodel.js
+++ b/web/floodlight/js/models/statusmodel.js
@@ -30,7 +30,7 @@
var self = this;
console.log("fetching controller status");
$.ajax({
- url:hackBase + "/wm/core/health/json",
+ url:hackBase + "/wm/floodlight/core/health/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: health");
@@ -39,7 +39,7 @@
}
});
$.ajax({
- url:hackBase + "/wm/core/system/uptime/json",
+ url:hackBase + "/wm/floodlight/core/system/uptime/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: uptime");
@@ -48,7 +48,7 @@
}
});
$.ajax({
- url:hackBase + "/wm/core/memory/json",
+ url:hackBase + "/wm/floodlight/core/memory/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: memory");
@@ -57,7 +57,7 @@
}
});
$.ajax({
- url:hackBase + "/wm/core/module/loaded/json",
+ url:hackBase + "/wm/floodlight/core/module/loaded/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: modules loaded");
diff --git a/web/js/models/switchmodel.js b/web/floodlight/js/models/switchmodel.js
similarity index 95%
rename from web/js/models/switchmodel.js
rename to web/floodlight/js/models/switchmodel.js
index 4104dd0..700a1cf 100644
--- a/web/js/models/switchmodel.js
+++ b/web/floodlight/js/models/switchmodel.js
@@ -16,7 +16,7 @@
window.Switch = Backbone.Model.extend({
- urlRoot:"/wm/core/switch/",
+ urlRoot:"/wm/floodlight/core/switch/",
defaults: {
datapathDescription: '',
@@ -34,7 +34,7 @@
//console.log("fetching switch " + this.id + " desc")
$.ajax({
- url:hackBase + "/wm/core/switch/" + self.id + '/desc/json',
+ url:hackBase + "/wm/floodlight/core/switch/" + self.id + '/desc/json',
dataType:"json",
success:function (data) {
//console.log("fetched switch " + self.id + " desc");
@@ -45,7 +45,7 @@
//console.log("fetching switch " + this.id + " aggregate")
$.ajax({
- url:hackBase + "/wm/core/switch/" + self.id + '/aggregate/json',
+ url:hackBase + "/wm/floodlight/core/switch/" + self.id + '/aggregate/json',
dataType:"json",
success:function (data) {
//console.log("fetched switch " + self.id + " aggregate");
@@ -69,7 +69,7 @@
//console.log("fetching switch " + this.id + " ports")
//console.log("fetching switch " + this.id + " features")
$.when($.ajax({
- url:hackBase + "/wm/core/switch/" + self.id + '/port/json',
+ url:hackBase + "/wm/floodlight/core/switch/" + self.id + '/port/json',
dataType:"json",
success:function (data) {
//console.log("fetched switch " + self.id + " ports");
@@ -106,7 +106,7 @@
}
}),
$.ajax({
- url:hackBase + "/wm/core/switch/" + self.id + '/features/json',
+ url:hackBase + "/wm/floodlight/core/switch/" + self.id + '/features/json',
dataType:"json",
success:function (data) {
//console.log("fetched switch " + self.id + " features");
@@ -163,7 +163,7 @@
var self = this;
//console.log("fetching switch " + this.id + " flows")
$.ajax({
- url:hackBase + "/wm/core/switch/" + self.id + '/flow/json',
+ url:hackBase + "/wm/floodlight/core/switch/" + self.id + '/flow/json',
dataType:"json",
success:function (data) {
//console.log("fetched switch " + self.id + " flows");
@@ -269,7 +269,7 @@
var self = this;
//console.log("fetching switch list")
$.ajax({
- url:hackBase + "/wm/core/controller/switches/json",
+ url:hackBase + "/wm/floodlight/core/controller/switches/json",
dataType:"json",
success:function (data) {
//console.log("fetched switch list: " + data.length);
diff --git a/web/js/models/topologymodel.js b/web/floodlight/js/models/topologymodel.js
similarity index 97%
rename from web/js/models/topologymodel.js
rename to web/floodlight/js/models/topologymodel.js
index c5d8f9b..bcac141 100644
--- a/web/js/models/topologymodel.js
+++ b/web/floodlight/js/models/topologymodel.js
@@ -16,7 +16,7 @@
window.Topology = Backbone.Model.extend({
- url:"/wm/topology/links/json",
+ url:"/wm/onos/linkdiscovery/links/json",
defaults:{
nodes: [],
diff --git a/web/js/onos-topology-route.js b/web/floodlight/js/onos-topology-route.js
similarity index 100%
rename from web/js/onos-topology-route.js
rename to web/floodlight/js/onos-topology-route.js
diff --git a/web/js/onos-topology.js b/web/floodlight/js/onos-topology.js
similarity index 100%
rename from web/js/onos-topology.js
rename to web/floodlight/js/onos-topology.js
diff --git a/web/js/utils.js b/web/floodlight/js/utils.js
similarity index 100%
rename from web/js/utils.js
rename to web/floodlight/js/utils.js
diff --git a/web/js/views/flow.js b/web/floodlight/js/views/flow.js
similarity index 100%
rename from web/js/views/flow.js
rename to web/floodlight/js/views/flow.js
diff --git a/web/js/views/header.js b/web/floodlight/js/views/header.js
similarity index 100%
rename from web/js/views/header.js
rename to web/floodlight/js/views/header.js
diff --git a/web/js/views/home.js b/web/floodlight/js/views/home.js
similarity index 100%
rename from web/js/views/home.js
rename to web/floodlight/js/views/home.js
diff --git a/web/js/views/host.js b/web/floodlight/js/views/host.js
similarity index 100%
rename from web/js/views/host.js
rename to web/floodlight/js/views/host.js
diff --git a/web/js/views/port.js b/web/floodlight/js/views/port.js
similarity index 100%
rename from web/js/views/port.js
rename to web/floodlight/js/views/port.js
diff --git a/web/js/views/status.js b/web/floodlight/js/views/status.js
similarity index 100%
rename from web/js/views/status.js
rename to web/floodlight/js/views/status.js
diff --git a/web/js/views/switch.js b/web/floodlight/js/views/switch.js
similarity index 100%
rename from web/js/views/switch.js
rename to web/floodlight/js/views/switch.js
diff --git a/web/js/views/topology.js b/web/floodlight/js/views/topology.js
similarity index 100%
rename from web/js/views/topology.js
rename to web/floodlight/js/views/topology.js
diff --git a/web/lib/backbone-min.js b/web/floodlight/lib/backbone-min.js
similarity index 100%
rename from web/lib/backbone-min.js
rename to web/floodlight/lib/backbone-min.js
diff --git a/web/lib/bootstrap-alert.js b/web/floodlight/lib/bootstrap-alert.js
similarity index 100%
rename from web/lib/bootstrap-alert.js
rename to web/floodlight/lib/bootstrap-alert.js
diff --git a/web/lib/bootstrap-dropdown.js b/web/floodlight/lib/bootstrap-dropdown.js
similarity index 100%
rename from web/lib/bootstrap-dropdown.js
rename to web/floodlight/lib/bootstrap-dropdown.js
diff --git a/web/lib/d3.v2.min.js b/web/floodlight/lib/d3.v2.min.js
similarity index 100%
rename from web/lib/d3.v2.min.js
rename to web/floodlight/lib/d3.v2.min.js
diff --git a/web/lib/jquery.min.js b/web/floodlight/lib/jquery.min.js
similarity index 100%
rename from web/lib/jquery.min.js
rename to web/floodlight/lib/jquery.min.js
diff --git a/web/lib/underscore-min.js b/web/floodlight/lib/underscore-min.js
similarity index 100%
rename from web/lib/underscore-min.js
rename to web/floodlight/lib/underscore-min.js
diff --git a/web/tpl/flow-list-item.html b/web/floodlight/tpl/flow-list-item.html
similarity index 100%
rename from web/tpl/flow-list-item.html
rename to web/floodlight/tpl/flow-list-item.html
diff --git a/web/tpl/flow-list.html b/web/floodlight/tpl/flow-list.html
similarity index 100%
rename from web/tpl/flow-list.html
rename to web/floodlight/tpl/flow-list.html
diff --git a/web/tpl/header.html b/web/floodlight/tpl/header.html
similarity index 100%
rename from web/tpl/header.html
rename to web/floodlight/tpl/header.html
diff --git a/web/tpl/home.html b/web/floodlight/tpl/home.html
similarity index 100%
rename from web/tpl/home.html
rename to web/floodlight/tpl/home.html
diff --git a/web/tpl/host-list-item.html b/web/floodlight/tpl/host-list-item.html
similarity index 100%
rename from web/tpl/host-list-item.html
rename to web/floodlight/tpl/host-list-item.html
diff --git a/web/tpl/host-list.html b/web/floodlight/tpl/host-list.html
similarity index 100%
rename from web/tpl/host-list.html
rename to web/floodlight/tpl/host-list.html
diff --git a/web/tpl/host.html b/web/floodlight/tpl/host.html
similarity index 100%
rename from web/tpl/host.html
rename to web/floodlight/tpl/host.html
diff --git a/web/tpl/port-list-item.html b/web/floodlight/tpl/port-list-item.html
similarity index 100%
rename from web/tpl/port-list-item.html
rename to web/floodlight/tpl/port-list-item.html
diff --git a/web/tpl/port-list.html b/web/floodlight/tpl/port-list.html
similarity index 100%
rename from web/tpl/port-list.html
rename to web/floodlight/tpl/port-list.html
diff --git a/web/tpl/status.html b/web/floodlight/tpl/status.html
similarity index 100%
rename from web/tpl/status.html
rename to web/floodlight/tpl/status.html
diff --git a/web/tpl/switch-list-item.html b/web/floodlight/tpl/switch-list-item.html
similarity index 100%
rename from web/tpl/switch-list-item.html
rename to web/floodlight/tpl/switch-list-item.html
diff --git a/web/tpl/switch-list.html b/web/floodlight/tpl/switch-list.html
similarity index 100%
rename from web/tpl/switch-list.html
rename to web/floodlight/tpl/switch-list.html
diff --git a/web/tpl/switch.html b/web/floodlight/tpl/switch.html
similarity index 100%
rename from web/tpl/switch.html
rename to web/floodlight/tpl/switch.html
diff --git a/web/tpl/topology.html b/web/floodlight/tpl/topology.html
similarity index 100%
rename from web/tpl/topology.html
rename to web/floodlight/tpl/topology.html
diff --git a/web/tpl/vlan-list-item.html b/web/floodlight/tpl/vlan-list-item.html
similarity index 100%
rename from web/tpl/vlan-list-item.html
rename to web/floodlight/tpl/vlan-list-item.html
diff --git a/web/tpl/vlan.html b/web/floodlight/tpl/vlan.html
similarity index 100%
rename from web/tpl/vlan.html
rename to web/floodlight/tpl/vlan.html
diff --git a/web/flowsync.py b/web/flowsync.py
index 51399d5..ef1d9bd 100755
--- a/web/flowsync.py
+++ b/web/flowsync.py
@@ -29,12 +29,12 @@
if DEBUG:
print '%s' % (txt)
-# @app.route("/wm/fprog/synchronizer/sync/<dpid>/json")
+# @app.route("/wm/onos/flowprogrammer/synchronizer/sync/<dpid>/json")
# Sample output:
# "true"
def synchronize(dpid):
try:
- command = "curl -s \"http://%s:%s/wm/fprog/synchronizer/sync/%s/json\"" % (ControllerIP, ControllerPort, dpid)
+ command = "curl -s \"http://%s:%s/wm/onos/flowprogrammer/synchronizer/sync/%s/json\"" % (ControllerIP, ControllerPort, dpid)
debug("synchronize %s" % command)
result = os.popen(command).read()
@@ -48,12 +48,12 @@
print "Synchronization of switch %s has successfully began" % (dpid)
-# @app.route("/wm/fprog/synchronizer/interrupt/<dpid>/json")
+# @app.route("/wm/onos/flowprogrammer/synchronizer/interrupt/<dpid>/json")
# Sample output:
# "true"
def interrupt(dpid):
try:
- command = "curl -s \"http://%s:%s/wm/fprog/synchronizer/interrupt/%s/json\"" % (ControllerIP, ControllerPort, dpid)
+ command = "curl -s \"http://%s:%s/wm/onos/flowprogrammer/synchronizer/interrupt/%s/json\"" % (ControllerIP, ControllerPort, dpid)
debug("interrupt %s" % command)
result = os.popen(command).read()
diff --git a/web/get_datagrid.py b/web/get_datagrid.py
index 2d26846..43ab04f 100755
--- a/web/get_datagrid.py
+++ b/web/get_datagrid.py
@@ -29,7 +29,7 @@
if DEBUG:
print '%s' % (txt)
-# @app.route("/wm/datagrid/get/map/<map-name>/json ")
+# @app.route("/wm/onos/datagrid/get/map/<map-name>/json ")
# Sample output:
def print_datagrid_map(parsedResult):
@@ -37,7 +37,7 @@
def get_datagrid_map(map_name):
try:
- command = "curl -s \"http://%s:%s/wm/datagrid/get/map/%s/json\"" % (ControllerIP, ControllerPort, map_name)
+ command = "curl -s \"http://%s:%s/wm/onos/datagrid/get/map/%s/json\"" % (ControllerIP, ControllerPort, map_name)
debug("get_datagrid_map %s" % command)
result = os.popen(command).read()
diff --git a/web/get_flow.py b/web/get_flow.py
index 94b9a61..382238f 100755
--- a/web/get_flow.py
+++ b/web/get_flow.py
@@ -29,7 +29,7 @@
if DEBUG:
print '%s' % (txt)
-# @app.route("/wm/flow/get/<flow-id>/json")
+# @app.route("/wm/onos/flows/get/<flow-id>/json")
# Sample output:
# {"flowId":{"value":"0x5"},"installerId":{"value":"FOOBAR"},"dataPath":{"srcPort":{"dpid":{"value":"00:00:00:00:00:00:00:01"},"port":{"value":0}},"dstPort":{"dpid":{"value":"00:00:00:00:00:00:00:02"},"port":{"value":0}},"flowEntries":[{"flowEntryId":"0x1389","flowEntryMatch":null,"flowEntryActions":null,"dpid":{"value":"00:00:00:00:00:00:00:01"},"inPort":{"value":0},"outPort":{"value":1},"flowEntryUserState":"FE_USER_DELETE","flowEntrySwitchState":"FE_SWITCH_NOT_UPDATED","flowEntryErrorState":null},{"flowEntryId":"0x138a","flowEntryMatch":null,"flowEntryActions":null,"dpid":{"value":"00:00:00:00:00:00:00:02"},"inPort":{"value":9},"outPort":{"value":0},"flowEntryUserState":"FE_USER_DELETE","flowEntrySwitchState":"FE_SWITCH_NOT_UPDATED","flowEntryErrorState":null}]}}
@@ -236,7 +236,7 @@
def get_flow_path(flow_id):
try:
- command = "curl -s \"http://%s:%s/wm/flow/get/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
+ command = "curl -s \"http://%s:%s/wm/onos/flows/get/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
debug("get_flow_path %s" % command)
result = os.popen(command).read()
@@ -256,7 +256,7 @@
def get_all_flow_paths():
try:
- command = "curl -s \"http://%s:%s/wm/flow/getall/json\"" % (ControllerIP, ControllerPort)
+ command = "curl -s \"http://%s:%s/wm/onos/flows/getall/json\"" % (ControllerIP, ControllerPort)
debug("get_all_flow_paths %s" % command)
result = os.popen(command).read()
diff --git a/web/onos-topology-route.html b/web/onos-topology-route.html
index 6c167c7..cbda5e9 100644
--- a/web/onos-topology-route.html
+++ b/web/onos-topology-route.html
@@ -42,7 +42,7 @@
</marker>
</defs>
<script type="text/javascript">
-gui("http://onosnat.onlab.us:8080/wm/topology/toporoute/00:00:00:0d:00:d1/2/00:00:00:0d:00:d3/3/json");
+gui("http://onosnat.onlab.us:8080/wm/floodlight/topology/toporoute/00:00:00:0d:00:d1/2/00:00:00:0d:00:d3/3/json");
</script>
</svg>
</body>
diff --git a/web/ons-demo/js/model.js b/web/ons-demo/js/model.js
index df4a751..bb1aaea 100644
--- a/web/ons-demo/js/model.js
+++ b/web/ons-demo/js/model.js
@@ -61,12 +61,12 @@
}
var urls = {
- links: '/wm/core/topology/links/json',
- switches: '/wm/core/topology/switches/all/json',
- flows: '/wm/flow/getsummary/0/0/json?proxy',
- activeControllers: '/wm/registry/controllers/json',
+ links: '/wm/onos/topology/links/json',
+ switches: '/wm/onos/topology/switches/all/json',
+ flows: '/wm/onos/flows/getsummary/0/0/json?proxy',
+ activeControllers: '/wm/onos/registry/controllers/json',
controllers: 'data/controllers.json',
- mapping: '/wm/registry/switches/json',
+ mapping: '/wm/onos/registry/switches/json',
configuration: 'data/configuration.json'
}
@@ -81,12 +81,12 @@
}
var proxyURLs = {
- links: '/wm/core/topology/links/json?proxy',
- switches: '/wm/core/topology/switches/all/json?proxy',
- flows: '/wm/flow/getsummary/0/0/json?proxy',
- activeControllers: '/wm/registry/controllers/json?proxy',
+ links: '/wm/onos/topology/links/json?proxy',
+ switches: '/wm/onos/topology/switches/all/json?proxy',
+ flows: '/wm/onos/flows/getsummary/0/0/json?proxy',
+ activeControllers: '/wm/onos/registry/controllers/json?proxy',
controllers: 'data/controllers.json',
- mapping: '/wm/registry/switches/json?proxy',
+ mapping: '/wm/onos/registry/switches/json?proxy',
configuration: 'data/configuration.json'
}
diff --git a/web/pusher.py b/web/pusher.py
index 2a3528b..dbbe7f9 100755
--- a/web/pusher.py
+++ b/web/pusher.py
@@ -29,12 +29,12 @@
if DEBUG:
print '%s' % (txt)
-# @app.route("/wm/fprog/pusher/setrate/<dpid>/<rate>/json")
+# @app.route("/wm/onos/flowprogrammer/pusher/setrate/<dpid>/<rate>/json")
# Sample output:
# "true"
def set_rate(dpid,rate):
try:
- command = "curl -s \"http://%s:%s/wm/fprog/pusher/setrate/%s/%s/json\"" % (ControllerIP, ControllerPort, dpid, rate)
+ command = "curl -s \"http://%s:%s/wm/onos/flowprogrammer/pusher/setrate/%s/%s/json\"" % (ControllerIP, ControllerPort, dpid, rate)
debug("set_rate %s" % command)
result = os.popen(command).read()
@@ -48,12 +48,12 @@
print "Sending rate to %s is successfully set to %s" % (dpid, rate)
-# @app.route("/wm/fprog/pusher/suspend/<dpid>/json")
+# @app.route("/wm/onos/flowprogrammer/pusher/suspend/<dpid>/json")
# Sample output:
# "true"
def suspend(dpid):
try:
- command = "curl -s \"http://%s:%s/wm/fprog/pusher/suspend/%s/json\"" % (ControllerIP, ControllerPort, dpid)
+ command = "curl -s \"http://%s:%s/wm/onos/flowprogrammer/pusher/suspend/%s/json\"" % (ControllerIP, ControllerPort, dpid)
debug("suspend %s" % command)
result = os.popen(command).read()
@@ -67,12 +67,12 @@
print "DPID %s is successfully suspended" % dpid
-# @app.route("/wm/fprog/pusher/resume/<dpid>/json")
+# @app.route("/wm/onos/flowprogrammer/pusher/resume/<dpid>/json")
# Sample output:
# "true"
def resume(dpid):
try:
- command = "curl -s \"http://%s:%s/wm/fprog/pusher/resume/%s/json\"" % (ControllerIP, ControllerPort, dpid)
+ command = "curl -s \"http://%s:%s/wm/onos/flowprogrammer/pusher/resume/%s/json\"" % (ControllerIP, ControllerPort, dpid)
debug("resume %s" % command)
result = os.popen(command).read()
@@ -86,12 +86,12 @@
print "DPID %s is successfully resumed" % dpid
-# @app.route("/wm/fprog/pusher/barrier/<dpid>/json")
+# @app.route("/wm/onos/flowprogrammer/pusher/barrier/<dpid>/json")
# Sample output:
# "{"version":1,"type":"BARRIER_REPLY","length":8,"xid":4,"lengthU":8}"
def barrier(dpid):
try:
- command = "curl -s \"http://%s:%s/wm/fprog/pusher/barrier/%s/json\"" % (ControllerIP, ControllerPort, dpid)
+ command = "curl -s \"http://%s:%s/wm/onos/flowprogrammer/pusher/barrier/%s/json\"" % (ControllerIP, ControllerPort, dpid)
debug("barrier %s" % command)
result = os.popen(command).read()
diff --git a/web/rest-test.sh b/web/rest-test.sh
index 2551f12..c6c870b 100755
--- a/web/rest-test.sh
+++ b/web/rest-test.sh
@@ -2,7 +2,7 @@
rm -f rest.json
touch rest.json
-urls="http://localhost:8080/wm/core/topology/switches/all/json http://localhost:8080/wm/core/topology/links/json http://localhost:8080/wm/registry/controllers/json http://localhost:8080/wm/registry/switches/json"
+urls="http://localhost:8080/wm/onos/topology/switches/all/json http://localhost:8080/wm/onos/linkdiscovery/links/json http://localhost:8080/wm/onos/registry/controllers/json http://localhost:8080/wm/onos/registry/switches/json"
for url in $urls; do
echo "---REST CALL---" >> rest.json
diff --git a/web/restapi.py b/web/restapi.py
index a3bd51c..fd99ac6 100755
--- a/web/restapi.py
+++ b/web/restapi.py
@@ -54,21 +54,21 @@
return response
## REST API ##
-#@app.route("/wm/topology/links/json")
+#@app.route("/wm/onos/linkdiscovery/links/json")
#def links():
# global links_
# js = json.dumps(links_)
# resp = Response(js, status=200, mimetype='application/json')
# return resp
-#@app.route("/wm/core/controller/switches/json")
+#@app.route("/wm/floodlight/core/controller/switches/json")
#def switches():
# global switches_
# js = json.dumps(switches_)
# resp = Response(js, status=200, mimetype='application/json')
# return resp
-@app.route("/wm/device/")
+@app.route("/wm/floodlight/device/")
def devices():
ret = []
js = json.dumps(ret)
@@ -76,7 +76,7 @@
return resp
## return fake stat for now
-@app.route("/wm/core/switch/<switchId>/<statType>/json")
+@app.route("/wm/floodlight/core/switch/<switchId>/<statType>/json")
def switch_stat(switchId, statType):
if statType == "desc":
desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
@@ -93,7 +93,7 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/core/controller/switches/json")
+@app.route("/wm/floodlight/core/controller/switches/json")
def query_switch():
try:
command = "curl -s http://%s:%s/graphs/%s/vertices" % (RestIP, RestPort, DBName)
@@ -116,7 +116,7 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/topology/links/json")
+@app.route("/wm/onos/linkdiscovery/links/json")
def query_links():
try:
command = "curl -s http://%s:%s/graphs/%s/edges" % (RestIP, RestPort, DBName)
diff --git a/web/restapi2.py b/web/restapi2.py
index c9952ac..050d8a4 100755
--- a/web/restapi2.py
+++ b/web/restapi2.py
@@ -57,7 +57,7 @@
ONOS_GUI3_HOST="http://gui3.onlab.us:8080"
ONOS_LOCAL_HOST="http://localhost:8080" ;# for Amazon EC2
-@app.route("/wm/core/topology/switches/all/json")
+@app.route("/wm/onos/topology/switches/all/json")
def switches():
if request.args.get('proxy') == None:
host = ONOS_LOCAL_HOST
@@ -65,7 +65,7 @@
host = ONOS_GUI3_HOST
try:
- command = "curl -s %s/wm/core/topology/switches/all/json" % (host)
+ command = "curl -s %s/wm/onos/topology/switches/all/json" % (host)
print command
result = os.popen(command).read()
except:
@@ -75,7 +75,7 @@
resp = Response(result, status=200, mimetype='application/json')
return resp
-@app.route("/wm/core/topology/links/json")
+@app.route("/wm/onos/topology/links/json")
def links():
if request.args.get('proxy') == None:
host = ONOS_LOCAL_HOST
@@ -83,7 +83,7 @@
host = ONOS_GUI3_HOST
try:
- command = "curl -s %s/wm/core/topology/links/json" % (host)
+ command = "curl -s %s/wm/onos/topology/links/json" % (host)
print command
result = os.popen(command).read()
except:
@@ -93,7 +93,7 @@
resp = Response(result, status=200, mimetype='application/json')
return resp
-@app.route("/wm/flow/getall/json")
+@app.route("/wm/onos/flows/getall/json")
def flows():
if request.args.get('proxy') == None:
host = ONOS_LOCAL_HOST
@@ -101,7 +101,7 @@
host = ONOS_GUI3_HOST
try:
- command = "curl -s %s/wm/flow/getall/json" % (host)
+ command = "curl -s %s/wm/onos/flows/getall/json" % (host)
print command
result = os.popen(command).read()
except:
@@ -111,7 +111,7 @@
resp = Response(result, status=200, mimetype='application/json')
return resp
-@app.route("/wm/registry/controllers/json")
+@app.route("/wm/onos/registry/controllers/json")
def registry_controllers():
if request.args.get('proxy') == None:
host = ONOS_LOCAL_HOST
@@ -119,7 +119,7 @@
host = ONOS_GUI3_HOST
try:
- command = "curl -s %s/wm/registry/controllers/json" % (host)
+ command = "curl -s %s/wm/onos/registry/controllers/json" % (host)
print command
result = os.popen(command).read()
except:
@@ -129,7 +129,7 @@
resp = Response(result, status=200, mimetype='application/json')
return resp
-@app.route("/wm/registry/switches/json")
+@app.route("/wm/onos/registry/switches/json")
def registry_switches():
if request.args.get('proxy') == None:
host = ONOS_LOCAL_HOST
@@ -137,7 +137,7 @@
host = ONOS_GUI3_HOST
try:
- command = "curl -s %s/wm/registry/switches/json" % (host)
+ command = "curl -s %s/wm/onos/registry/switches/json" % (host)
print command
result = os.popen(command).read()
except:
@@ -151,21 +151,21 @@
## REST API ##
-#@app.route("/wm/topology/links/json")
+#@app.route("/wm/onos/linkdiscovery/links/json")
#def links():
# global links_
# js = json.dumps(links_)
# resp = Response(js, status=200, mimetype='application/json')
# return resp
-#@app.route("/wm/core/controller/switches/json")
+#@app.route("/wm/floodlight/core/controller/switches/json")
#def switches():
# global switches_
# js = json.dumps(switches_)
# resp = Response(js, status=200, mimetype='application/json')
# return resp
-@app.route("/wm/device/")
+@app.route("/wm/floodlight/device/")
def devices():
try:
command = "curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=device" % (RestIP, RestPort, DBName)
@@ -218,7 +218,7 @@
#{"entityClass":"DefaultEntityClass","mac":["7c:d1:c3:e0:8c:a3"],"ipv4":["192.168.2.102","10.1.10.35"],"vlan":[],"attachmentPoint":[{"port":13,"switchDPID":"00:01:00:12:e2:78:32:44","errorStatus":null}],"lastSeen":1357333593496}
## return fake stat for now
-@app.route("/wm/core/switch/<switchId>/<statType>/json")
+@app.route("/wm/floodlight/core/switch/<switchId>/<statType>/json")
def switch_stat(switchId, statType):
if statType == "desc":
desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
@@ -235,7 +235,7 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/core/controller/switches/json")
+@app.route("/wm/floodlight/core/controller/switches/json")
def query_switch():
try:
command = "curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=switch" % (RestIP, RestPort, DBName)
@@ -258,7 +258,7 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/topology/links/json")
+@app.route("/wm/onos/linkdiscovery/links/json")
def query_links():
try:
command = "curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=port" % (RestIP, RestPort, DBName)
diff --git a/web/restapi3.py b/web/restapi3.py
index 001faa6..f3bb3eb 100755
--- a/web/restapi3.py
+++ b/web/restapi3.py
@@ -137,7 +137,7 @@
return response
-@app.route("/wm/device/")
+@app.route("/wm/floodlight/device/")
def devices():
try:
command = "curl -s http://%s:%s/graphs/%s/vertices\?key=type\&value=device" % (RestIP, RestPort, DBName)
@@ -182,7 +182,7 @@
## return fake stat for now
-@app.route("/wm/core/switch/<switchId>/<statType>/json")
+@app.route("/wm/floodlight/core/switch/<switchId>/<statType>/json")
def switch_stat(switchId, statType):
if statType == "desc":
desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
@@ -199,7 +199,7 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/core/controller/switches/json")
+@app.route("/wm/floodlight/core/controller/switches/json")
def query_switch():
try:
command = "curl -s \'http://%s:%s/graphs/%s/vertices?key=type&value=switch\'" % (RestIP, RestPort, DBName)
@@ -226,7 +226,7 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/topology/links/json")
+@app.route("/wm/onos/linkdiscovery/links/json")
def query_links():
try:
command = 'curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=port' % (RestIP, RestPort, DBName)
diff --git a/web/shortest_path.py b/web/shortest_path.py
index 0f23bf4..805224b 100755
--- a/web/shortest_path.py
+++ b/web/shortest_path.py
@@ -13,7 +13,7 @@
from flask import Flask, json, Response, render_template, make_response, request
#
-# curl http://127.0.0.1:8080/wm/topology/route/00:00:00:00:00:00:0a:01/1/00:00:00:00:00:00:0a:04/1/json
+# curl http://127.0.0.1:8080/wm/onos/topology/route/00:00:00:00:00:00:0a:01/1/00:00:00:00:00:00:0a:04/1/json
#
## Global Var ##
@@ -33,14 +33,14 @@
if DEBUG:
print '%s' % (txt)
-# @app.route("/wm/topology/route/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
+# @app.route("/wm/onos/topology/route/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
#
# Sample output:
# {'dstPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:02'}}, 'srcPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:01'}}, 'flowEntries': [{'outPort': {'value': 1}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 0}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:01'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}, {'outPort': {'value': 0}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 9}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:02'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}]}
#
def shortest_path(v1, p1, v2, p2):
try:
- command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (ControllerIP, ControllerPort, v1, p1, v2, p2)
+ command = "curl -s http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (ControllerIP, ControllerPort, v1, p1, v2, p2)
debug("shortest_path %s" % command)
result = os.popen(command).read()
diff --git a/web/topology_rest.py b/web/topology_rest.py
index b3a415e..38dba5d 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -273,69 +273,69 @@
return "http://" + host + ":8080"
## Switch ##
-@app.route("/wm/core/topology/switches/all/json")
+@app.route("/wm/onos/topology/switches/all/json")
def switches():
if request.args.get('proxy') == None:
host = pick_host()
else:
host = ONOS_GUI3_HOST
- url ="%s/wm/core/topology/switches/all/json" % (host)
+ url ="%s/wm/onos/topology/switches/all/json" % (host)
(code, result) = get_json(url)
resp = Response(result, status=code, mimetype='application/json')
return resp
## Link ##
-@app.route("/wm/core/topology/links/json")
+@app.route("/wm/onos/topology/links/json")
def links():
if request.args.get('proxy') == None:
host = pick_host()
else:
host = ONOS_GUI3_HOST
- url ="%s/wm/core/topology/links/json" % (host)
+ url ="%s/wm/onos/topology/links/json" % (host)
(code, result) = get_json(url)
resp = Response(result, status=code, mimetype='application/json')
return resp
## FlowSummary ##
-@app.route("/wm/flow/getsummary/<start>/<range>/json")
+@app.route("/wm/onos/flows/getsummary/<start>/<range>/json")
def flows(start, range):
if request.args.get('proxy') == None:
host = pick_host()
else:
host = ONOS_GUI3_HOST
- url ="%s/wm/flow/getsummary/%s/%s/json" % (host, start, range)
+ url ="%s/wm/onos/flows/getsummary/%s/%s/json" % (host, start, range)
(code, result) = get_json(url)
resp = Response(result, status=code, mimetype='application/json')
return resp
-@app.route("/wm/registry/controllers/json")
+@app.route("/wm/onos/registry/controllers/json")
def registry_controllers():
if request.args.get('proxy') == None:
host = pick_host()
else:
host = ONOS_GUI3_HOST
- url= "%s/wm/registry/controllers/json" % (host)
+ url= "%s/wm/onos/registry/controllers/json" % (host)
(code, result) = get_json(url)
resp = Response(result, status=code, mimetype='application/json')
return resp
-@app.route("/wm/registry/switches/json")
+@app.route("/wm/onos/registry/switches/json")
def registry_switches():
if request.args.get('proxy') == None:
host = pick_host()
else:
host = ONOS_GUI3_HOST
- url="%s/wm/registry/switches/json" % (host)
+ url="%s/wm/onos/registry/switches/json" % (host)
(code, result) = get_json(url)
resp = Response(result, status=code, mimetype='application/json')
@@ -354,7 +354,7 @@
@app.route('/topology', methods=['GET'])
def topology_for_gui():
try:
- command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
+ command = "curl -s \'http://%s:%s/wm/onos/topology/switches/all/json\'" % (RestIP, RestPort)
result = os.popen(command).read()
parsedResult = json.loads(result)
except:
@@ -382,7 +382,7 @@
switches.append(sw)
try:
- command = "curl -s \'http://%s:%s/wm/registry/switches/json\'" % (RestIP, RestPort)
+ command = "curl -s \'http://%s:%s/wm/onos/registry/switches/json\'" % (RestIP, RestPort)
result = os.popen(command).read()
parsedResult = json.loads(result)
except:
@@ -404,7 +404,7 @@
# v2 = "00:00:00:00:00:0b:0d:03"
# v2 = "00:00:00:00:00:0d:00:d3"
# p2=1
-# command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
+# command = "curl -s http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
# result = os.popen(command).read()
# parsedResult = json.loads(result)
# except:
@@ -421,7 +421,7 @@
# path.append( (sdpid, ddpid))
try:
- command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
+ command = "curl -s \'http://%s:%s/wm/onos/topology/links/json\'" % (RestIP, RestPort)
result = os.popen(command).read()
parsedResult = json.loads(result)
except:
@@ -457,12 +457,12 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-#@app.route("/wm/topology/toporoute/00:00:00:00:00:a1/2/00:00:00:00:00:c1/3/json")
-#@app.route("/wm/topology/toporoute/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
-@app.route("/wm/topology/toporoute/<v1>/<p1>/<v2>/<p2>/json")
+#@app.route("/wm/floodlight/topology/toporoute/00:00:00:00:00:a1/2/00:00:00:00:00:c1/3/json")
+#@app.route("/wm/floodlight/topology/toporoute/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
+@app.route("/wm/floodlight/topology/toporoute/<v1>/<p1>/<v2>/<p2>/json")
def shortest_path(v1, p1, v2, p2):
try:
- command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
+ command = "curl -s \'http://%s:%s/wm/onos/topology/switches/all/json\'" % (RestIP, RestPort)
result = os.popen(command).read()
parsedResult = json.loads(result)
except:
@@ -494,7 +494,7 @@
switches.append(sw)
try:
- command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
+ command = "curl -s http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
result = os.popen(command).read()
parsedResult = json.loads(result)
except:
@@ -510,7 +510,7 @@
path.append( (sdpid, ddpid))
try:
- command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
+ command = "curl -s \'http://%s:%s/wm/onos/topology/links/json\'" % (RestIP, RestPort)
result = os.popen(command).read()
parsedResult = json.loads(result)
except:
@@ -545,11 +545,11 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/core/controller/switches/json")
+@app.route("/wm/floodlight/core/controller/switches/json")
def query_switch():
try:
- command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
-# http://localhost:8080/wm/core/topology/switches/active/json
+ command = "curl -s \'http://%s:%s/wm/onos/topology/switches/all/json\'" % (RestIP, RestPort)
+# http://localhost:8080/wm/onos/topology/switches/active/json
print command
result = os.popen(command).read()
parsedResult = json.loads(result)
@@ -577,7 +577,7 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/device/")
+@app.route("/wm/floodlight/device/")
def devices():
try:
command = "curl -s http://%s:%s/graphs/%s/vertices\?key=type\&value=device" % (RestIP, RestPort, DBName)
@@ -621,7 +621,7 @@
#{"entityClass":"DefaultEntityClass","mac":["7c:d1:c3:e0:8c:a3"],"ipv4":["192.168.2.102","10.1.10.35"],"vlan":[],"attachmentPoint":[{"port":13,"switchDPID":"00:01:00:12:e2:78:32:44","errorStatus":null}],"lastSeen":1357333593496}
## return fake stat for now
-@app.route("/wm/core/switch/<switchId>/<statType>/json")
+@app.route("/wm/floodlight/core/switch/<switchId>/<statType>/json")
def switch_stat(switchId, statType):
if statType == "desc":
desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
@@ -639,7 +639,7 @@
return resp
-@app.route("/wm/topology/links/json")
+@app.route("/wm/onos/linkdiscovery/links/json")
def query_links():
try:
command = 'curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=port' % (RestIP, RestPort, DBName)
@@ -955,7 +955,7 @@
@app.route("/gui/addflow/<src_dpid>/<src_port>/<dst_dpid>/<dst_port>/<srcMAC>/<dstMAC>")
def add_flow(src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC):
host = pick_host()
- url ="%s/wm/flow/getsummary/%s/%s/json" % (host, 0, 0)
+ url ="%s/wm/onos/flows/getsummary/%s/%s/json" % (host, 0, 0)
(code, result) = get_json(url)
parsedResult = json.loads(result)
if len(parsedResult) > 0:
@@ -990,7 +990,7 @@
@app.route("/gui/iperf/start/<flow_id>/<duration>/<samples>")
def iperf_start(flow_id,duration,samples):
try:
- command = "curl -s \'http://%s:%s/wm/flow/get/%s/json\'" % (RestIP, RestPort, flow_id)
+ command = "curl -s \'http://%s:%s/wm/onos/flows/get/%s/json\'" % (RestIP, RestPort, flow_id)
print command
result = os.popen(command).read()
if len(result) == 0:
@@ -1055,7 +1055,7 @@
@app.route("/gui/iperf/rate/<flow_id>")
def iperf_rate(flow_id):
try:
- command = "curl -s \'http://%s:%s/wm/flow/get/%s/json\'" % (RestIP, RestPort, flow_id)
+ command = "curl -s \'http://%s:%s/wm/onos/flows/get/%s/json\'" % (RestIP, RestPort, flow_id)
print command
result = os.popen(command).read()
if len(result) == 0: