Merge pull request #534 from n-shiota/bugfix
Removed FireBugs warnings.
diff --git a/cluster-mgmt/template/onsdemo_edge_template.py b/cluster-mgmt/template/onsdemo_edge_template.py
index c3d0287..b5a76f5 100755
--- a/cluster-mgmt/template/onsdemo_edge_template.py
+++ b/cluster-mgmt/template/onsdemo_edge_template.py
@@ -113,7 +113,7 @@
# controllers.append(rc)
#net.controllers=controllers
- net.build()
+ #net.build()
host = []
for i in range (NR_NODES):
diff --git a/kryo2/.gitignore b/kryo2/.gitignore
deleted file mode 100644
index 916e17c..0000000
--- a/kryo2/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-dependency-reduced-pom.xml
diff --git a/kryo2/pom.xml b/kryo2/pom.xml
deleted file mode 100644
index d81a16a..0000000
--- a/kryo2/pom.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>net.onrc.onos</groupId>
- <artifactId>kryo2</artifactId>
- <version>2.22</version>
- <packaging>jar</packaging>
-
- <name>kryo2</name>
- <url>http://maven.apache.org</url>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>com.esotericsoftware.kryo</groupId>
- <artifactId>kryo</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.1</version>
- <configuration>
- <relocations>
- <relocation>
- <pattern>com.esotericsoftware.kryo</pattern>
- <shadedPattern>com.esotericsoftware.kryo2</shadedPattern>
- <excludes>
- <exclude>com.esotericsoftware.kryo2*</exclude>
- </excludes>
- </relocation>
- </relocations>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
- <executions>
- <execution>
- <id>kryo2</id>
- <goals>
- <goal>exec</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <executable>mvn</executable>
- <commandlineArgs>install:install-file -DlocalRepositoryPath=${basedir}/../repo -DcreateChecksum=true -Dpackaging=jar -Dfile=${basedir}/target/${project.build.finalName}.jar -DgroupId=${project.groupId} -DartifactId=${project.artifactId} -Dversion=${project.version}</commandlineArgs>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/pom.xml b/pom.xml
index c0cf489..6a1b29d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -265,22 +265,11 @@
</plugins>
</reporting>
<dependencies>
- <!-- Commenting out original kryo 2.X
- and using shaded version (net.onrc.onos.kryo2)
- to workaround conflict with kryo 1.X in titan's dependency.(#443)
- -->
- <!--
<dependency>
<groupId>com.esotericsoftware.kryo</groupId>
<artifactId>kryo</artifactId>
<version>2.22</version>
</dependency>
- -->
- <dependency>
- <groupId>net.onrc.onos</groupId>
- <artifactId>kryo2</artifactId>
- <version>2.22</version>
- </dependency>
<!-- ONOS's direct dependencies -->
<dependency>
<groupId>org.apache.cassandra</groupId>
diff --git a/rebuild-local-repo.sh b/rebuild-local-repo.sh
index 558bcfb..1baa27b 100755
--- a/rebuild-local-repo.sh
+++ b/rebuild-local-repo.sh
@@ -15,11 +15,6 @@
MVN="mvn"
fi
-# Install Kryo2 workaround to local repo
-# - Shaded(rename package name to allow mixing 2 different Kryo version)
-# - Install created sharded jar to local repo
-${MVN} -f kryo2/pom.xml clean package exec:exec
-
# Install modified curators to local repo
${MVN} install:install-file -Dfile=./curator/curator-framework-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-framework -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true -DlocalRepositoryPath=./repo -DcreateChecksum=true
${MVN} install:install-file -Dfile=./curator/curator-client-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-client -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true -DlocalRepositoryPath=./repo -DcreateChecksum=true
diff --git a/scripts/all-linkup.sh b/scripts/all-linkup.sh
index 9067012..290a17d 100755
--- a/scripts/all-linkup.sh
+++ b/scripts/all-linkup.sh
@@ -3,11 +3,6 @@
controller=`hostname`
switches=`sudo ovs-vsctl list-br`
-function host2ip (){
- ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
- echo $ip
-}
-
for s in $switches; do
ports=`sudo ovs-vsctl --pretty list-ports $s`
for p in $ports; do
diff --git a/scripts/ctrl-local.sh b/scripts/ctrl-local.sh
index 023a9db..1418a2c 100755
--- a/scripts/ctrl-local.sh
+++ b/scripts/ctrl-local.sh
@@ -1,9 +1,8 @@
#! /bin/bash
controller=`hostname`
-switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
-
+switches=`sudo ovs-vsctl list-br`
function host2ip (){
- ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
+ ip=`getent hosts $1 | awk '{print $1}' | tail -n 1`
echo $ip
}
diff --git a/scripts/ctrl-none.sh b/scripts/ctrl-none.sh
index 74349e3..fb8d2a0 100755
--- a/scripts/ctrl-none.sh
+++ b/scripts/ctrl-none.sh
@@ -1,9 +1,8 @@
#! /bin/bash
controller=""
-switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
-
+switches=`sudo ovs-vsctl list-br`
function host2ip (){
- ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
+ ip=`getent hosts $1 | awk '{print $1}' | tail -n 1`
echo $ip
}
diff --git a/scripts/ctrl-one.sh b/scripts/ctrl-one.sh
index 207d3f2..9fe8341 100755
--- a/scripts/ctrl-one.sh
+++ b/scripts/ctrl-one.sh
@@ -8,10 +8,9 @@
#controller=`hostname`
controller=$1
-switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
-
+switches=`sudo ovs-vsctl list-br`
function host2ip (){
- ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
+ ip=`getent hosts $1 | awk '{print $1}' | tail -n 1`
echo $ip
}
diff --git a/scripts/link.sh b/scripts/link.sh
index dc202e7..57323ef 100755
--- a/scripts/link.sh
+++ b/scripts/link.sh
@@ -1,7 +1,7 @@
#! /bin/bash
controller=`hostname`
-switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
+switches=`sudo ovs-vsctl list-br`
function host2ip (){
ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
@@ -12,14 +12,16 @@
if [ $# != 3 ];then
echo "usage: $0 <dpid> <port> <up|down>"
+ echo " example: $0 00:00:00:00:ba:5e:ba:11 1 up"
+ exit
fi
-src_dpid="dpid:"`echo $1 | sed s'/://g'`
+src_dpid=`echo $1 | sed s'/://g'`
src_port=$2
cmd=$3
for s in $switches; do
- dpid=`sudo ovs-ofctl show $s |grep dpid | awk '{print $4}'`
+ dpid=`sudo ovs-ofctl show $s |grep dpid | awk '{if(match($0,/dpid:[0-9|a-d]*/)){ print substr($0,RSTART+5,RLENGTH)}}'`
if [ "x$dpid" == "x$src_dpid" ]; then
# intf=`sudo ovs-ofctl show $s |grep addr | awk -v p=$src_port 'BEGIN {pat="^ "p"\("}
diff --git a/scripts/showdpid.sh b/scripts/showdpid.sh
index 1dff291..14b6345 100755
--- a/scripts/showdpid.sh
+++ b/scripts/showdpid.sh
@@ -2,17 +2,6 @@
controller=""
#switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
switches=`sudo ovs-vsctl list-br`
-
-function host2ip (){
- ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
- echo $ip
-}
-
-url=""
-for c in $controller; do
- url="$url tcp:`host2ip $c`:6633"
-done
-echo $url
for s in $switches; do
echo -n "$s : "
sudo ovs-ofctl show $s |grep dpid
diff --git a/scripts/showflow.sh b/scripts/showflow.sh
index 15824d7..63b82b7 100755
--- a/scripts/showflow.sh
+++ b/scripts/showflow.sh
@@ -2,11 +2,6 @@
controller=""
switches=`sudo ovs-vsctl list-br`
-function host2ip (){
- ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
- echo $ip
-}
-
dpids=()
for s in $switches; do
i=`sudo ovs-ofctl show $s |grep dpid | awk -F ":" '{print $4}'`
diff --git a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
index 0c7be88..5be4191 100644
--- a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
+++ b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
@@ -32,9 +32,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.esotericsoftware.kryo2.Kryo;
-import com.esotericsoftware.kryo2.io.Input;
-import com.esotericsoftware.kryo2.io.Output;
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
import com.hazelcast.config.Config;
import com.hazelcast.config.FileSystemXmlConfig;
import com.hazelcast.core.EntryEvent;
@@ -80,14 +80,14 @@
private IMap<String, byte[]> mapTopology = null;
private MapTopologyListener mapTopologyListener = null;
private String mapTopologyListenerId = null;
-
+
// State related to the packet out map
protected static final String packetOutMapName = "packetOutMap";
private IMap<PacketOutNotification, byte[]> packetOutMap = null;
private List<IPacketOutEventHandler> packetOutEventHandlers = new ArrayList<IPacketOutEventHandler>();
private final byte[] dummyByte = {0};
-
+
// State related to the ARP reply map
protected static final String arpReplyMapName = "arpReplyMap";
private IMap<ArpReplyNotification, byte[]> arpReplyMap = null;
@@ -337,6 +337,7 @@
*
* @param event the notification event for the entry.
*/
+ @Override
public void entryAdded(EntryEvent<PacketOutNotification, byte[]> event) {
for (IPacketOutEventHandler packetOutEventHandler : packetOutEventHandlers) {
packetOutEventHandler.packetOutNotification(event.getKey());
@@ -348,6 +349,7 @@
*
* @param event the notification event for the entry.
*/
+ @Override
public void entryRemoved(EntryEvent<PacketOutNotification, byte[]> event) {
// Not used
}
@@ -357,6 +359,7 @@
*
* @param event the notification event for the entry.
*/
+ @Override
public void entryUpdated(EntryEvent<PacketOutNotification, byte[]> event) {
// Not used
}
@@ -366,11 +369,12 @@
*
* @param event the notification event for the entry.
*/
+ @Override
public void entryEvicted(EntryEvent<PacketOutNotification, byte[]> event) {
// Not used
}
}
-
+
/**
* Class for receiving notifications for sending packet-outs.
*
@@ -384,15 +388,19 @@
*
* @param event the notification event for the entry.
*/
+ @Override
public void entryAdded(EntryEvent<ArpReplyNotification, byte[]> event) {
for (IArpReplyEventHandler arpReplyEventHandler : arpReplyEventHandlers) {
arpReplyEventHandler.arpReplyEvent(event.getKey());
}
}
-
+
// These methods aren't used for ARP replies
+ @Override
public void entryRemoved(EntryEvent<ArpReplyNotification, byte[]> event) {}
+ @Override
public void entryUpdated(EntryEvent<ArpReplyNotification, byte[]> event) {}
+ @Override
public void entryEvicted(EntryEvent<ArpReplyNotification, byte[]> event) {}
}
@@ -511,10 +519,10 @@
hazelcastInstance = Hazelcast.newHazelcastInstance(hazelcastConfig);
restApi.addRestletRoutable(new DatagridWebRoutable());
-
+
packetOutMap = hazelcastInstance.getMap(packetOutMapName);
packetOutMap.addEntryListener(new PacketOutMapListener(), true);
-
+
arpReplyMap = hazelcastInstance.getMap(arpReplyMapName);
arpReplyMap.addEntryListener(new ArpReplyMapListener(), true);
}
@@ -582,12 +590,12 @@
packetOutEventHandlers.add(packetOutEventHandler);
}
}
-
+
@Override
public void deregisterPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler) {
packetOutEventHandlers.remove(packetOutEventHandler);
}
-
+
@Override
public void registerArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler) {
if (arpReplyEventHandler != null) {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index d16b8b4..b11d6d8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -1017,12 +1017,12 @@
}
OFMatch matchLLDP = new OFMatch();
- matchLLDP.setDataLayerType((short)0x8942);
+ matchLLDP.setDataLayerType((short)0x88cc);
matchLLDP.setWildcards(matchLLDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
fmLLDP.setMatch(matchLLDP);
OFMatch matchBDDP = new OFMatch();
- matchBDDP.setDataLayerType((short)0x88cc);
+ matchBDDP.setDataLayerType((short)0x8942);
matchBDDP.setWildcards(matchBDDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
fmBDDP.setMatch(matchBDDP);
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 e075bad..c3d7501 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -4,8 +4,6 @@
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.LinkedList;
-import java.util.List;
-
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.graph.GraphDBOperation;
@@ -221,7 +219,7 @@
flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
flowEntryObj.setType("flow_entry");
- //
+ //
// Set the Flow Entry Edges and attributes:
// - Switch edge
// - InPort edge
@@ -373,24 +371,15 @@
* @return true on success, otherwise false.
*/
static boolean deleteAllFlows(GraphDBOperation dbHandler) {
- List<FlowId> allFlowIds = new LinkedList<FlowId>();
-
// Get all Flow IDs
Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
for (IFlowPath flowPathObj : allFlowPaths) {
if (flowPathObj == null)
continue;
- String flowIdStr = flowPathObj.getFlowId();
- if (flowIdStr == null)
- continue;
- FlowId flowId = new FlowId(flowIdStr);
- allFlowIds.add(flowId);
- }
- // Delete all flows one-by-one
- for (FlowId flowId : allFlowIds) {
- deleteFlow(dbHandler, flowId);
+ deleteIFlowPath(dbHandler, flowPathObj);
}
+ dbHandler.commit();
return true;
}
@@ -417,6 +406,18 @@
return true; // OK: No such flow
}
+ deleteIFlowPath(dbHandler, flowObj);
+ dbHandler.commit();
+ return true;
+ }
+
+ /**
+ * Delete a previously added flow.
+ * @note You need to call commit after calling this method.
+ * @param dbHandler the Graph Database handler to use.
+ * @param flowObj IFlowPath object to delete.
+ */
+ private static void deleteIFlowPath(GraphDBOperation dbHandler, IFlowPath flowObj) {
//
// Remove all Flow Entries
//
@@ -427,9 +428,6 @@
}
// Remove the Flow itself
dbHandler.removeFlowPath(flowObj);
- dbHandler.commit();
-
- return true;
}
/**
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 8b1f7c0..7550cfd 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -31,7 +31,7 @@
import net.onrc.onos.ofcontroller.util.FlowPathUserState;
import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
-import com.esotericsoftware.kryo2.Kryo;
+import com.esotericsoftware.kryo.Kryo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -273,6 +273,10 @@
for (FlowPath flowPath : flowPaths) {
boolean isInstalled = true;
+
+ if (flowPath.flowEntries().isEmpty()) {
+ continue;
+ }
//
// Check whether all Flow Entries have been installed
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index dd98f4e..f266163 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -39,7 +39,7 @@
import com.thinkaurelius.titan.core.TitanException;
-import com.esotericsoftware.kryo2.Kryo;
+import com.esotericsoftware.kryo.Kryo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -400,6 +400,11 @@
if (srcDpid.value() != sw.getId())
return;
deleteFlow(flowPath.flowId());
+
+ // Send flow deleted notification to the Forwarding module
+ // TODO This is a quick fix for flow-removed notifications. We
+ // should think more about the design of these notifications.
+ notificationFlowPathRemoved(flowPath);
}
/**
@@ -469,6 +474,20 @@
}
/**
+ * Generate a notification that a FlowPath has been removed from the
+ * network. This means we've received an expiry message for the flow
+ * from the switch, and send flowmods to remove any remaining parts of
+ * the path.
+ *
+ * @param flowPath FlowPath object that was removed from the network.
+ */
+ void notificationFlowPathRemoved(FlowPath flowPath) {
+ if (forwardingService != null) {
+ forwardingService.flowRemoved(flowPath);
+ }
+ }
+
+ /**
* Push modified Flow-related state as appropriate.
*
* @param modifiedFlowPaths the collection of modified Flow Paths.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
index 6d953f1..b3d9759 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -25,12 +25,13 @@
import net.onrc.onos.ofcontroller.devicemanager.IOnosDeviceService;
import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
-import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
import net.onrc.onos.ofcontroller.proxyarp.BroadcastPacketOutNotification;
+import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
import net.onrc.onos.ofcontroller.topology.TopologyManager;
import net.onrc.onos.ofcontroller.util.CallerId;
import net.onrc.onos.ofcontroller.util.DataPath;
import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
import net.onrc.onos.ofcontroller.util.FlowId;
import net.onrc.onos.ofcontroller.util.FlowPath;
@@ -59,8 +60,8 @@
private final int IDLE_TIMEOUT = 5; // seconds
private final int HARD_TIMEOUT = 0; // seconds
-
- private final int PATH_PUSHED_TIMEOUT = 3000; // milliseconds
+
+ private final CallerId callerId = new CallerId("Forwarding");
private IFloodlightProviderService floodlightProvider;
private IFlowService flowService;
@@ -70,7 +71,6 @@
private IDeviceStorage deviceStorage;
private TopologyManager topologyService;
- //private Map<Path, Long> pendingFlows;
// TODO it seems there is a Guava collection that will time out entries.
// We should see if this will work here.
private Map<Path, PushedFlow> pendingFlows;
@@ -90,31 +90,18 @@
private class PushedFlow {
public final long flowId;
- private final long pushedTime;
- public short firstHopOutPort = OFPort.OFPP_NONE.getValue();
+ public boolean installed = false;
public PushedFlow(long flowId) {
this.flowId = flowId;
- pushedTime = System.currentTimeMillis();
- }
-
- public boolean isExpired() {
- return (System.currentTimeMillis() - pushedTime) > PATH_PUSHED_TIMEOUT;
}
}
private final class Path {
- public final SwitchPort srcPort;
- public final SwitchPort dstPort;
public final MACAddress srcMac;
public final MACAddress dstMac;
- public Path(SwitchPort src, SwitchPort dst,
- MACAddress srcMac, MACAddress dstMac) {
- srcPort = new SwitchPort(new Dpid(src.dpid().value()),
- new Port(src.port().value()));
- dstPort = new SwitchPort(new Dpid(dst.dpid().value()),
- new Port(dst.port().value()));
+ public Path(MACAddress srcMac, MACAddress dstMac) {
this.srcMac = srcMac;
this.dstMac = dstMac;
}
@@ -126,17 +113,13 @@
}
Path otherPath = (Path) other;
- return srcPort.equals(otherPath.srcPort) &&
- dstPort.equals(otherPath.dstPort) &&
- srcMac.equals(otherPath.srcMac) &&
+ return srcMac.equals(otherPath.srcMac) &&
dstMac.equals(otherPath.dstMac);
}
@Override
public int hashCode() {
int hash = 17;
- hash = 31 * hash + srcPort.hashCode();
- hash = 31 * hash + dstPort.hashCode();
hash = 31 * hash + srcMac.hashCode();
hash = 31 * hash + dstMac.hashCode();
return hash;
@@ -144,8 +127,7 @@
@Override
public String toString() {
- return "(" + srcMac + " at " + srcPort + ") => ("
- + dstPort + " at " + dstMac + ")";
+ return "(" + srcMac + ") => (" + dstMac + ")";
}
}
@@ -188,12 +170,8 @@
datagrid = context.getServiceImpl(IDatagridService.class);
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-
- //pendingFlows = new ConcurrentHashMap<Path, Long>();
+
pendingFlows = new HashMap<Path, PushedFlow>();
- //waitingPackets = Multimaps.synchronizedSetMultimap(
- //HashMultimap.<Long, PacketToPush>create());
- //waitingPackets = HashMultimap.create();
waitingPackets = LinkedListMultimap.create();
deviceStorage = new DeviceStorageImpl();
@@ -243,7 +221,6 @@
if (eth.isBroadcast() || eth.isMulticast()) {
handleBroadcast(sw, pi, eth);
- //return Command.CONTINUE;
}
else {
// Unicast
@@ -297,26 +274,50 @@
MACAddress srcMacAddress = MACAddress.valueOf(eth.getSourceMACAddress());
MACAddress dstMacAddress = MACAddress.valueOf(eth.getDestinationMACAddress());
-
FlowPath flowPath, reverseFlowPath;
- Path pathspec = new Path(srcSwitchPort, dstSwitchPort,
- srcMacAddress, dstMacAddress);
+ Path pathspec = new Path(srcMacAddress, dstMacAddress);
// TODO check concurrency
synchronized (lock) {
PushedFlow existingFlow = pendingFlows.get(pathspec);
- //Long existingFlowId = pendingFlows.get(pathspec);
-
- if (existingFlow != null && !existingFlow.isExpired()) {
+
+ if (existingFlow != null) {
+ // We've already installed a flow for this pair of MAC addresses
log.debug("Found existing flow {}",
HexString.toHexString(existingFlow.flowId));
OFPacketOut po = constructPacketOut(pi, sw);
- if (existingFlow.firstHopOutPort != OFPort.OFPP_NONE.getValue()) {
+ // Find the correct port here. We just assume the PI is from
+ // the first hop switch, but this is definitely not always
+ // the case. We'll have to retrieve the flow from HZ every time
+ // because it could change (be rerouted) sometimes.
+ if (existingFlow.installed) {
// Flow has been sent to the switches so it is safe to
// send a packet out now
- sendPacketOut(sw, po, existingFlow.firstHopOutPort);
+ FlowPath flow = datagrid.getFlow(new FlowId(existingFlow.flowId));
+ FlowEntry flowEntryForThisSwitch = null;
+
+ if (flow != null) {
+ for (FlowEntry flowEntry : flow.flowEntries()) {
+ if (flowEntry.dpid().equals(new Dpid(sw.getId()))) {
+ flowEntryForThisSwitch = flowEntry;
+ break;
+ }
+ }
+ }
+
+ if (flowEntryForThisSwitch == null) {
+ // If we don't find a flow entry for that switch, then we're
+ // in the middle of a rerouting (or something's gone wrong).
+ // This packet will be dropped as a victim of the rerouting.
+ log.debug("Dropping packet on flow {} between {}-{}, flow path {}",
+ new Object[] {new FlowId(existingFlow.flowId),
+ srcMacAddress, dstMacAddress, flow});
+ }
+ else {
+ sendPacketOut(sw, po, flowEntryForThisSwitch.outPort().value());
+ }
}
else {
// Flow has not yet been sent to switches so save the
@@ -326,21 +327,16 @@
}
return;
}
-
- //log.debug("Couldn't match {} in {}", pathspec, pendingFlows);
-
+
log.debug("Adding new flow between {} at {} and {} at {}",
new Object[]{srcMacAddress, srcSwitchPort, dstMacAddress, dstSwitchPort});
-
- CallerId callerId = new CallerId("Forwarding");
-
DataPath datapath = new DataPath();
datapath.setSrcPort(srcSwitchPort);
datapath.setDstPort(dstSwitchPort);
flowPath = new FlowPath();
- flowPath.setInstallerId(callerId);
+ flowPath.setInstallerId(new CallerId(callerId));
flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
@@ -360,7 +356,7 @@
// TODO implement copy constructor for FlowPath
reverseFlowPath = new FlowPath();
- reverseFlowPath.setInstallerId(callerId);
+ reverseFlowPath.setInstallerId(new CallerId(callerId));
reverseFlowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
reverseFlowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
reverseFlowPath.setIdleTimeout(IDLE_TIMEOUT);
@@ -372,9 +368,7 @@
reverseFlowPath.flowEntryMatch().enableEthernetFrameType(Ethernet.TYPE_IPv4);
reverseFlowPath.setDataPath(reverseDataPath);
reverseFlowPath.dataPath().srcPort().dpid().toString();
-
- // TODO what happens if no path exists? cleanup
-
+
FlowId flowId = new FlowId(flowService.getNextFlowEntryId());
FlowId reverseFlowId = new FlowId(flowService.getNextFlowEntryId());
@@ -382,50 +376,23 @@
reverseFlowPath.setFlowId(reverseFlowId);
OFPacketOut po = constructPacketOut(pi, sw);
- Path reversePathSpec = new Path(dstSwitchPort, srcSwitchPort,
- dstMacAddress, srcMacAddress);
+ Path reversePathSpec = new Path(dstMacAddress, srcMacAddress);
// Add to waiting lists
- //pendingFlows.put(pathspec, flowId.value());
- //pendingFlows.put(reversePathSpec, reverseFlowId.value());
pendingFlows.put(pathspec, new PushedFlow(flowId.value()));
pendingFlows.put(reversePathSpec, new PushedFlow(reverseFlowId.value()));
waitingPackets.put(flowId.value(), new PacketToPush(po, sw.getId()));
}
+ log.debug("Adding reverse {} to {} flowid {}", new Object[] {
+ dstMacAddress, srcMacAddress, reverseFlowPath.flowId()});
flowService.addFlow(reverseFlowPath);
+ log.debug("Adding forward {} to {} flowid {}", new Object[] {
+ srcMacAddress, dstMacAddress, flowPath.flowId()});
flowService.addFlow(flowPath);
}
-
- /*
- private boolean flowExists(SwitchPort srcPort, MACAddress srcMac,
- SwitchPort dstPort, MACAddress dstMac) {
- for (FlowPath flow : datagridService.getAllFlows()) {
- FlowEntryMatch match = flow.flowEntryMatch();
- // TODO implement FlowEntryMatch.equals();
- // This is painful to do properly without support in the FlowEntryMatch
- boolean same = true;
- if (!match.srcMac().equals(srcMac) ||
- !match.dstMac().equals(dstMac)) {
- same = false;
- }
- if (!flow.dataPath().srcPort().equals(srcPort) ||
- !flow.dataPath().dstPort().equals(dstPort)) {
- same = false;
- }
-
- if (same) {
- log.debug("found flow entry that's the same {}-{}:::{}-{}",
- new Object[] {srcPort, srcMac, dstPort, dstMac});
- return true;
- }
- }
-
- return false;
- }
- */
private OFPacketOut constructPacketOut(OFPacketIn pi, IOFSwitch sw) {
OFPacketOut po = new OFPacketOut();
@@ -452,36 +419,64 @@
flowInstalled(flowPath);
}
}
+
+ @Override
+ public void flowRemoved(FlowPath removedFlowPath) {
+ if (!removedFlowPath.installerId().equals(callerId)) {
+ // Not our flow path, ignore
+ return;
+ }
+
+ MACAddress srcMacAddress = removedFlowPath.flowEntryMatch().srcMac();
+ MACAddress dstMacAddress = removedFlowPath.flowEntryMatch().dstMac();
+
+ Path removedPath = new Path(srcMacAddress, dstMacAddress);
+
+ synchronized (lock) {
+ pendingFlows.remove(removedPath);
+
+ // There *shouldn't* be any packets queued if the flow has
+ // just been removed.
+ List<PacketToPush> packets =
+ waitingPackets.removeAll(removedFlowPath.flowId().value());
+ if (!packets.isEmpty()) {
+ log.warn("Removed flow {} has packets queued",
+ removedFlowPath.flowId());
+ }
+ }
+ }
private void flowInstalled(FlowPath installedFlowPath) {
long flowId = installedFlowPath.flowId().value();
+ if (!installedFlowPath.installerId().equals(callerId)) {
+ // Not our flow path, ignore
+ return;
+ }
+
+ // TODO waiting packets should time out. We could request a path that
+ // can't be installed right now because of a network partition. The path
+ // may eventually be installed, but we may have received thousands of
+ // packets in the meantime and probably don't want to send very old packets.
short outPort =
installedFlowPath.flowEntries().get(0).outPort().value();
MACAddress srcMacAddress = installedFlowPath.flowEntryMatch().srcMac();
MACAddress dstMacAddress = installedFlowPath.flowEntryMatch().dstMac();
- if (srcMacAddress == null || dstMacAddress == null) {
- // Not our flow path, ignore
- return;
- }
-
Collection<PacketToPush> packets;
synchronized (lock) {
- log.debug("Flow {} has been installed, sending queued packets",
- installedFlowPath.flowId());
-
packets = waitingPackets.removeAll(flowId);
+ log.debug("Flow {} has been installed, sending {} queued packets",
+ installedFlowPath.flowId(), packets.size());
+
// remove pending flows entry
- Path installedPath = new Path(installedFlowPath.dataPath().srcPort(),
- installedFlowPath.dataPath().dstPort(),
- srcMacAddress, dstMacAddress);
- //pendingFlows.remove(pathToRemove);
+ Path installedPath = new Path(srcMacAddress, dstMacAddress);
PushedFlow existingFlow = pendingFlows.get(installedPath);
- if (existingFlow != null)
- existingFlow.firstHopOutPort = outPort;
+ if (existingFlow != null) {
+ existingFlow.installed = true;
+ }
}
for (PacketToPush packet : packets) {
@@ -499,4 +494,5 @@
flowPusher.add(sw, po);
}
+
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
index e5bd714..0e0d1da 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
@@ -22,4 +22,12 @@
* been installed in the network.
*/
public void flowsInstalled(Collection<FlowPath> installedFlowPaths);
+
+ /**
+ * Notify the Forwarding module that a flow has expired and been
+ * removed from the network.
+ *
+ * @param removedFlowPath The FlowPath that was removed
+ */
+ public void flowRemoved(FlowPath removedFlowPath);
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java b/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
index 0607533..a0217d4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
@@ -12,6 +12,15 @@
* Default constructor.
*/
public CallerId() {}
+
+ /**
+ * Copy constructor
+ * @param otherCallerId
+ */
+ public CallerId(CallerId otherCallerId) {
+ // Note: make a full copy if we change value to a mutable type
+ value = otherCallerId.value;
+ }
/**
* Constructor from a string value.
@@ -49,4 +58,20 @@
public String toString() {
return value;
}
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof CallerId)) {
+ return false;
+ }
+
+ CallerId otherCallerId = (CallerId) other;
+
+ return value.equals(otherCallerId.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
index 883f830..5998dcd 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
@@ -30,7 +30,7 @@
import net.onrc.onos.ofcontroller.util.Switch;
import net.onrc.onos.ofcontroller.util.SwitchPort;
-import com.esotericsoftware.kryo2.Kryo;
+import com.esotericsoftware.kryo.Kryo;
/**
* Class factory for allocating Kryo instances for
diff --git a/start-onos.sh b/start-onos.sh
index b1fed60..899cd34 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -19,6 +19,7 @@
## If you want JaCoCo Code Coverage reports... uncomment line below
#JVM_OPTS="$JVM_OPTS -javaagent:${ONOS_HOME}/lib/jacocoagent.jar=dumponexit=true,output=file,destfile=${LOGDIR}/jacoco.exec"
JVM_OPTS="$JVM_OPTS -server -d64"
+#JVM_OPTS="$JVM_OPTS -XX:+TieredCompilation -XX:InitialCodeCacheSize=512m -XX:ReservedCodeCacheSize=512m"
#JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
#JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
diff --git a/start-rest.sh b/start-rest.sh
index 910eb41..94bbd46 100755
--- a/start-rest.sh
+++ b/start-rest.sh
@@ -57,6 +57,10 @@
function start {
lotate $REST_LOG 10
cd $WEBDIR
+ # Make log dir for iperf log files
+ if [ ! -d log ]; then
+ mkdir log
+ fi
$restscript > $REST_LOG 2>&1 &
}
diff --git a/test-network/mininet/dev_network_edge.py b/test-network/mininet/dev_network_edge.py
index 29be6ad..acc5d0d 100755
--- a/test-network/mininet/dev_network_edge.py
+++ b/test-network/mininet/dev_network_edge.py
@@ -113,7 +113,6 @@
# controllers.append(rc)
#net.controllers=controllers
- net.build()
host = []
for i in range (NR_NODES):
diff --git a/test-network/mininet/dev_network_edge_2.py b/test-network/mininet/dev_network_edge_2.py
index 50dc00c..553b376 100755
--- a/test-network/mininet/dev_network_edge_2.py
+++ b/test-network/mininet/dev_network_edge_2.py
@@ -113,7 +113,6 @@
# controllers.append(rc)
#net.controllers=controllers
- net.build()
host = []
for i in range (NR_NODES):
diff --git a/web/js/onos-topology.js b/web/js/onos-topology.js
index 3772127..d086f6a 100644
--- a/web/js/onos-topology.js
+++ b/web/js/onos-topology.js
@@ -222,8 +222,23 @@
return changed
}
+ function nr_active_sw(){
+ var n=0;
+ var nodes = force.nodes();
+ for(var i=0;i<nodes.length;i++){
+ if(nodes[i].group!=0)
+ n++;
+ };
+ return n;
+ }
+
function draw(force, path, circle, text){
force.stop();
+ svg.append("svg:text")
+ .attr("x", 50)
+ .attr("y", 20)
+ .text(function(){return "Switch: " + force.nodes().length + " (Active: " + nr_active_sw() + ")/ Link: " + force.links().length});
+
path.enter().append("svg:path")
.attr("class", function(d) { return "link"; })
.attr("marker-end", function(d) {
diff --git a/web/onos-topology.html b/web/onos-topology.html
index 5834521..b4e5097 100644
--- a/web/onos-topology.html
+++ b/web/onos-topology.html
@@ -43,7 +43,7 @@
<path d="M0,-5L10,0L0,5" fill="red" stroke="red"/>
</marker>
</defs>
-<h1>ONOS Sprint 4 Demo GUI</h1>
+<h1>ONOS Simple Topology GUI</h1>
<h2>Controller Status</h2>
<div id="servers"></div>
<div id="onos-status"></div>
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 38dba5d..0b0ab01 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -8,8 +8,8 @@
import io
import time
import random
-
import re
+from urllib2 import Request, urlopen, URLError, HTTPError
from flask import Flask, json, Response, render_template, make_response, request
@@ -114,132 +114,131 @@
## Proxy ##
@app.route("/proxy/gui/link/<cmd>/<src_dpid>/<src_port>/<dst_dpid>/<dst_port>")
def proxy_link_change(cmd, src_dpid, src_port, dst_dpid, dst_port):
+ url = "%s/gui/link/%s/%s/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, src_dpid, src_port, dst_dpid, dst_port)
try:
- command = "curl -s %s/gui/link/%s/%s/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, src_dpid, src_port, dst_dpid, dst_port)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
+ result = ""
+ print "REST IF has issue %s" % url
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/switchctrl/<cmd>")
def proxy_switch_controller_setting(cmd):
+ url = "%s/gui/switchctrl/%s" % (ONOS_GUI3_CONTROL_HOST, cmd)
try:
- command = "curl -s %s/gui/switchctrl/%s" % (ONOS_GUI3_CONTROL_HOST, cmd)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
+ result = ""
+ print "REST IF has issue %s" % url
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/switch/<cmd>/<dpid>")
def proxy_switch_status_change(cmd, dpid):
+ url = "%s/gui/switch/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, dpid)
try:
- command = "curl -s %s/gui/switch/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, dpid)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
+ result = ""
+ print "REST IF has issue %s" % url
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/controller/<cmd>/<controller_name>")
def proxy_controller_status_change(cmd, controller_name):
+ url = "%s/gui/controller/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, controller_name)
try:
- command = "curl -s %s/gui/controller/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, controller_name)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
-
+ result = ""
+ print "REST IF has issue %s" % url
+
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/addflow/<src_dpid>/<src_port>/<dst_dpid>/<dst_port>/<srcMAC>/<dstMAC>")
def proxy_add_flow(src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC):
try:
- command = "curl -s %s/gui/addflow/%s/%s/%s/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC)
- print command
- result = os.popen(command).read()
+ url = "%s/gui/addflow/%s/%s/%s/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC)
+ #print "proxy gui addflow " + url
+ (code, result) = get_json(url)
except:
- print "REST IF has issue"
- exit
+ print "REST IF has issue %s" % url
+ print "Result %s" % result
+ exit()
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/delflow/<flow_id>")
def proxy_del_flow(flow_id):
+ url = "%s/gui/delflow/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
try:
- command = "curl -s %s/gui/delflow/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
+ result = ""
+ print "REST IF has issue %s" % url
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/iperf/start/<flow_id>/<duration>/<samples>")
def proxy_iperf_start(flow_id,duration,samples):
+ url = "%s/gui/iperf/start/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id, duration, samples)
try:
- command = "curl -m 40 -s %s/gui/iperf/start/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id, duration, samples)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
+ result = ""
+ print "REST IF has issue %s" % url
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/iperf/rate/<flow_id>")
def proxy_iperf_rate(flow_id):
+ url = "%s/gui/iperf/rate/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
try:
- command = "curl -s %s/gui/iperf/rate/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
+ result = ""
+ print "REST IF has issue %s" % url
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/reset")
def proxy_gui_reset():
- result = ""
+ url = "%s/gui/reset" % (ONOS_GUI3_CONTROL_HOST)
try:
- command = "curl -m 300 -s %s/gui/reset" % (ONOS_GUI3_CONTROL_HOST)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
+ result = ""
+ print "REST IF has issue %s" % url
resp = Response(result, status=200, mimetype='application/json')
return resp
@app.route("/proxy/gui/scale")
def proxy_gui_scale():
- result = ""
+ url = "%s/gui/scale" % (ONOS_GUI3_CONTROL_HOST)
try:
- command = "curl -m 300 -s %s/gui/scale" % (ONOS_GUI3_CONTROL_HOST)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- print "REST IF has issue"
- exit
+ result = ""
+ print "REST IF has issue %s" % url
resp = Response(result, status=200, mimetype='application/json')
return resp
@@ -247,19 +246,20 @@
###### ONOS REST API ##############################
## Worker Func ###
def get_json(url):
- code = 200
+ code = 200;
try:
- command = "curl -m 60 -s %s" % (url)
- result = os.popen(command).read()
- parsedResult = json.loads(result)
- if type(parsedResult) == 'dict' and parsedResult.has_key('code'):
- print "REST %s returned code %s" % (command, parsedResult['code'])
- code=500
- except:
- print "REST IF %s has issue" % command
+ response = urlopen(url)
+ except URLError, e:
+ print "get_json: REST IF %s has issue. Reason: %s" % (url, e.reason)
result = ""
- code = 500
+ return (500, result)
+ except HTTPError, e:
+ print "get_json: REST IF %s has issue. Code %s" % (url, e.code)
+ result = ""
+ return (e.code, result)
+ result = response.read()
+# parsedResult = json.loads(result)
return (code, result)
def pick_host():
@@ -354,14 +354,13 @@
@app.route('/topology', methods=['GET'])
def topology_for_gui():
try:
- command = "curl -s \'http://%s:%s/wm/onos/topology/switches/all/json\'" % (RestIP, RestPort)
- result = os.popen(command).read()
+ url="http://%s:%s/wm/onos/topology/switches/all/json" % (RestIP, RestPort)
+ (code, result) = get_json(url)
parsedResult = json.loads(result)
except:
- log_error("REST IF has issue: %s" % command)
+ log_error("REST IF has issue: %s" % url)
log_error("%s" % result)
return
-# sys.exit(0)
topo = {}
switches = []
@@ -382,11 +381,11 @@
switches.append(sw)
try:
- command = "curl -s \'http://%s:%s/wm/onos/registry/switches/json\'" % (RestIP, RestPort)
- result = os.popen(command).read()
+ url="http://%s:%s/wm/onos/registry/switches/json" % (RestIP, RestPort)
+ (code, result) = get_json(url)
parsedResult = json.loads(result)
except:
- log_error("REST IF has issue: %s" % command)
+ log_error("REST IF has issue: %s" % url)
log_error("%s" % result)
for key in parsedResult:
@@ -397,35 +396,12 @@
if switches[sw_id]['group'] != 0:
switches[sw_id]['group'] = controllers.index(ctrl) + 1
-# try:
-# v1 = "00:00:00:00:00:0a:0d:00"
-# v1 = "00:00:00:00:00:0d:00:d1"
-# p1=1
-# 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/onos/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
-# result = os.popen(command).read()
-# parsedResult = json.loads(result)
-# except:
-# log_error("No route")
-# parsedResult = {}
-
- #path = []
- #if parsedResult.has_key('flowEntries'):
- # flowEntries= parsedResult['flowEntries']
- # for i, v in enumerate(flowEntries):
- # if i < len(flowEntries) - 1:
- # sdpid= flowEntries[i]['dpid']['value']
- # ddpid = flowEntries[i+1]['dpid']['value']
- # path.append( (sdpid, ddpid))
-
try:
- command = "curl -s \'http://%s:%s/wm/onos/topology/links/json\'" % (RestIP, RestPort)
- result = os.popen(command).read()
+ url = "http://%s:%s/wm/onos/topology/links/json" % (RestIP, RestPort)
+ (code, result) = get_json(url)
parsedResult = json.loads(result)
except:
- log_error("REST IF has issue: %s" % command)
+ log_error("REST IF has issue: %s" % url)
log_error("%s" % result)
return
# sys.exit(0)
@@ -457,19 +433,16 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-#@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/onos/topology/switches/all/json\'" % (RestIP, RestPort)
- result = os.popen(command).read()
+ url = "http://%s:%s/wm/onos/topology/switches/all/json" % (RestIP, RestPort)
+ (code, result) = get_json(url)
parsedResult = json.loads(result)
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
return
-# sys.exit(0)
topo = {}
switches = []
@@ -494,30 +467,28 @@
switches.append(sw)
try:
- 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()
+ url = "http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
+ (code, result) = get_json(url)
parsedResult = json.loads(result)
except:
log_error("No route")
parsedResult = []
-# exit(1)
path = [];
for i, v in enumerate(parsedResult):
if i < len(parsedResult) - 1:
- sdpid= parsedResult[i]['switch']
- ddpid = parsedResult[i+1]['switch']
+ sdpid= parsedResult['flowEntries'][i]['dpid']['value']
+ ddpid= parsedResult['flowEntries'][i+1]['dpid']['value']
path.append( (sdpid, ddpid))
try:
- command = "curl -s \'http://%s:%s/wm/onos/topology/links/json\'" % (RestIP, RestPort)
- result = os.popen(command).read()
+ url = "http://%s:%s/wm/onos/topology/links/json" % (RestIP, RestPort)
+ (code, result) = get_json(url)
parsedResult = json.loads(result)
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
return
-# sys.exit(0)
for v in parsedResult:
link = {}
@@ -548,13 +519,11 @@
@app.route("/wm/floodlight/core/controller/switches/json")
def query_switch():
try:
- 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()
+ url = "http://%s:%s/wm/onos/topology/switches/all/json" % (RestIP, RestPort)
+ (code, result) = get_json(url)
parsedResult = json.loads(result)
except:
- log_error("REST IF has issue: %s" % command)
+ log_error("REST IF has issue: %s" % url)
log_error("%s" % result)
return
# sys.exit(0)
@@ -577,49 +546,6 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-@app.route("/wm/floodlight/device/")
-def devices():
- try:
- command = "curl -s http://%s:%s/graphs/%s/vertices\?key=type\&value=device" % (RestIP, RestPort, DBName)
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue: %s" % command)
- log_error("%s" % result)
- return
-# sys.exit(0)
-
- devices = []
- for v in parsedResult:
- dl_addr = v['dl_addr']
- nw_addr = v['nw_addr']
- vertex = v['_id']
- mac = []
- mac.append(dl_addr)
- ip = []
- ip.append(nw_addr)
- device = {}
- device['entryClass']="DefaultEntryClass"
- device['mac']=mac
- device['ipv4']=ip
- device['vlan']=[]
- device['lastSeen']=0
- attachpoints =[]
-
- port, dpid = deviceV_to_attachpoint(vertex)
- attachpoint = {}
- attachpoint['port']=port
- attachpoint['switchDPID']=dpid
- attachpoints.append(attachpoint)
- device['attachmentPoint']=attachpoints
- devices.append(device)
-
- js = json.dumps(devices)
- resp = Response(js, status=200, mimetype='application/json')
- return resp
-
-#{"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/floodlight/core/switch/<switchId>/<statType>/json")
def switch_stat(switchId, statType):
@@ -638,68 +564,19 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-
-@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)
- print command
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue: %s" % command)
- log_error("%s" % result)
- return
-# sys.exit(0)
-
- debug("query_links %s" % command)
-# pp.pprint(parsedResult)
- sport = []
- links = []
- for v in parsedResult:
- srcport = v['_id']
- try:
- command = "curl -s http://%s:%s/graphs/%s/vertices/%d/out?_label=link" % (RestIP, RestPort, DBName, srcport)
- print command
- result = os.popen(command).read()
- linkResults = json.loads(result)['results']
- except:
- log_error("REST IF has issue: %s" % command)
- log_error("%s" % result)
- return
-# sys.exit(0)
-
- for p in linkResults:
- if p.has_key('type') and p['type'] == "port":
- dstport = p['_id']
- (sport, sdpid) = portV_to_port_dpid(srcport)
- (dport, ddpid) = portV_to_port_dpid(dstport)
- link = {}
- link["src-switch"]=sdpid
- link["src-port"]=sport
- link["src-port-state"]=0
- link["dst-switch"]=ddpid
- link["dst-port"]=dport
- link["dst-port-state"]=0
- link["type"]="internal"
- links.append(link)
-
-# pp.pprint(links)
- js = json.dumps(links)
- resp = Response(js, status=200, mimetype='application/json')
- return resp
-
@app.route("/controller_status")
def controller_status():
-# onos_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh status | awk '{print $1}'"
- onos_check="cd; onos status | grep %s | awk '{print $2}'"
- #cassandra_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-cassandra.sh status"
+ url= "http://%s:%d/wm/onos/registry/controllers/json" % (RestIP, RestPort)
+ (code, result) = get_json(url)
+ parsedResult = json.loads(result)
cont_status=[]
for i in controllers:
status={}
- onos=os.popen(onos_check % i).read()[:-1]
-# onos=os.popen(onos_check % (i, i.lower())).read()[:-1]
+ if i in parsedResult:
+ onos=1
+ else:
+ onos=0
status["name"]=i
status["onos"]=onos
status["cassandra"]=0
@@ -709,6 +586,7 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
+
### Command ###
@app.route("/gui/controller/<cmd>/<controller_name>")
def controller_status_change(cmd, controller_name):
@@ -989,17 +867,16 @@
#http://localhost:9000/gui/iperf/start/<flow_id>/<duration>
@app.route("/gui/iperf/start/<flow_id>/<duration>/<samples>")
def iperf_start(flow_id,duration,samples):
+ url = "http://%s:%s/wm/onos/flows/get/%s/json" % (RestIP, RestPort, flow_id)
try:
- command = "curl -s \'http://%s:%s/wm/onos/flows/get/%s/json\'" % (RestIP, RestPort, flow_id)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
if len(result) == 0:
print "No Flow found"
return "Flow %s not found" % (flow_id);
except:
- print "REST IF has issue"
- return "REST IF has issue"
- exit
+ print "REST IF has issue %s" % url
+ return "REST IF has issue %s" % url
parsedResult = json.loads(result)
@@ -1054,15 +931,14 @@
#http://localhost:9000/gui/iperf/rate/<flow_id>
@app.route("/gui/iperf/rate/<flow_id>")
def iperf_rate(flow_id):
+ url = "http://%s:%s/wm/onos/flows/get/%s/json" % (RestIP, RestPort, flow_id)
try:
- command = "curl -s \'http://%s:%s/wm/onos/flows/get/%s/json\'" % (RestIP, RestPort, flow_id)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
if len(result) == 0:
- resp = Response(result, status=400, mimetype='text/html')
- return "no such iperf flow (flowid %s)" % flow_id;
+ return "no such iperf flow (flowid %s)" % flow_id
except:
- print "REST IF has issue"
+ print "REST IF has issue %s" % url
exit
parsedResult = json.loads(result)
@@ -1082,12 +958,13 @@
else:
host = controllers[hostid-1]
+ url="http://%s:%s/log/iperfsvr_%s.out" % (host, 9000, flow_id)
try:
- command = "curl -s http://%s:%s/log/iperfsvr_%s.out" % (host, 9000, flow_id)
- print command
- result = os.popen(command).read()
+ response = urlopen(url)
+ result = response.read()
except:
- exit
+ print "REST IF has issue %s" % url
+ return
if re.match("Cannot", result):
resp = Response(result, status=400, mimetype='text/html')
@@ -1101,25 +978,24 @@
read_config()
read_link_def()
if len(sys.argv) > 1 and sys.argv[1] == "-d":
-# add_flow("00:00:00:00:00:00:02:02", 1, "00:00:00:00:00:00:03:02", 1, "00:00:00:00:02:02", "00:00:00:00:03:0c")
-# link_change("up", "00:00:00:00:ba:5e:ba:11", 1, "00:00:00:00:00:00:00:00", 1)
-# link_change("down", "00:00:20:4e:7f:51:8a:35", 1, "00:00:00:00:00:00:00:00", 1)
-# link_change("up", "00:00:00:00:00:00:02:03", 1, "00:00:00:00:00:00:00:00", 1)
-# link_change("down", "00:00:00:00:00:00:07:12", 1, "00:00:00:00:00:00:00:00", 1)
-# print "-- query all switches --"
-# query_switch()
-# print "-- query topo --"
-# topology_for_gui()
-# link_change(1,2,3,4)
- print "-- query all links --"
-# query_links()
-# print "-- query all devices --"
-# devices()
-# iperf_start(1,10,15)
-# iperf_rate(1)
-# switches()
-# add_flow(1,2,3,4,5,6)
- reset_demo()
+ # for debugging
+ #add_flow("00:00:00:00:00:00:02:02", 1, "00:00:00:00:00:00:03:02", 1, "00:00:00:00:02:02", "00:00:00:00:03:0c")
+ #proxy_link_change("up", "00:00:00:00:ba:5e:ba:11", 1, "00:00:00:00:00:00:00:00", 1)
+ #proxy_link_change("down", "00:00:20:4e:7f:51:8a:35", 1, "00:00:00:00:00:00:00:00", 1)
+ #proxy_link_change("up", "00:00:00:00:00:00:02:03", 1, "00:00:00:00:00:00:00:00", 1)
+ #proxy_link_change("down", "00:00:00:00:00:00:07:12", 1, "00:00:00:00:00:00:00:00", 1)
+ #print "-- query all switches --"
+ #query_switch()
+ #print "-- query topo --"
+ #topology_for_gui()
+ ##print "-- query all links --"
+ ##query_links()
+ #print "-- query all devices --"
+ #devices()
+ #links()
+ #switches()
+ #reset_demo()
+ pass
else:
app.debug = True
app.run(threaded=True, host="0.0.0.0", port=9000)