Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONOS
diff --git a/build.xml b/build.xml
index 4aa99bf..e8055e7 100644
--- a/build.xml
+++ b/build.xml
@@ -66,9 +66,10 @@
<include name="concurrentlinkedhashmap-lru-1.3.jar"/>
<include name="jython-2.5.2.jar"/>
<include name="libthrift-0.7.0.jar"/>
- <include name="curator-client-1.3.1.jar"/>
- <include name="curator-framework-1.3.1.jar"/>
- <include name="curator-recipes-1.3.1.jar"/>
+ <include name="curator-client-1.3.3.jar"/>
+ <include name="curator-framework-1.3.3.jar"/>
+ <include name="curator-recipes-1.3.3.jar"/>
+ <include name="zookeeper-3.4.5.jar"/>
</patternset>
<patternset id="titanlib">
diff --git a/ctrl-add-ext-template.sh b/ctrl-add-ext-template.sh
index c8e7d25..6cbf565 100755
--- a/ctrl-add-ext-template.sh
+++ b/ctrl-add-ext-template.sh
@@ -1,5 +1,5 @@
#! /bin/bash
-controller="localhost onos9vpc onos10vpc onos11vpc"
+controller="onos9vpc onos10vpc onos11vpc"
me=`hostname`
controller=`echo $controller | sed "s/$me//g"`
switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
diff --git a/ctrl-local.sh b/ctrl-local.sh
index 79b421b..023a9db 100755
--- a/ctrl-local.sh
+++ b/ctrl-local.sh
@@ -1,5 +1,5 @@
#! /bin/bash
-controller="localhost"
+controller=`hostname`
switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
function host2ip (){
diff --git a/showdpid.sh b/showdpid.sh
new file mode 100755
index 0000000..91281a1
--- /dev/null
+++ b/showdpid.sh
@@ -0,0 +1,17 @@
+#! /bin/bash
+controller=""
+switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
+
+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
+ sudo ovs-ofctl show $s |grep dpid
+done
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
index 589c931..2c19f68 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
@@ -189,18 +189,6 @@
@Property("switch_dpid")
public void setSwitchDpid(String switchDpid);
- @Property("in_port")
- public Short getInPort();
-
- @Property("in_port")
- public void setInPort(Short inPort);
-
- @Property("out_port")
- public Short getOutPort();
-
- @Property("out_port")
- public void setOutPort(Short outPort);
-
@Property("user_state")
public String getUserState();
@@ -224,5 +212,47 @@
@Property("error_state_code")
public void setErrorStateCode(String errorStateCode);
+
+ @Property("matchInPort")
+ public Short getMatchInPort();
+
+ @Property("matchInPort")
+ public void setMatchInPort(Short matchInPort);
+
+ @Property("matchEthernetFrameType")
+ public Short getMatchEthernetFrameType();
+
+ @Property("matchEthernetFrameType")
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType);
+
+ @Property("matchSrcMac")
+ public String getMatchSrcMac();
+
+ @Property("matchSrcMac")
+ public void setMatchSrcMac(String matchSrcMac);
+
+ @Property("matchDstMac")
+ public String getMatchDstMac();
+
+ @Property("matchDstMac")
+ public void setMatchDstMac(String matchDstMac);
+
+ @Property("matchSrcIPv4Net")
+ public String getMatchSrcIPv4Net();
+
+ @Property("matchSrcIPv4Net")
+ public void setMatchSrcIPv4Net(String matchSrcIPv4Net);
+
+ @Property("matchDstIPv4Net")
+ public String getMatchDstIPv4Net();
+
+ @Property("matchDstIPv4Net")
+ public void setMatchDstIPv4Net(String matchDstIPv4Net);
+
+ @Property("actionOutput")
+ public Short getActionOutput();
+
+ @Property("actionOutput")
+ public void setActionOutput(Short actionOutput);
}
}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index 8cf1982..a604969 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -29,11 +29,15 @@
import net.floodlightcontroller.util.Dpid;
import net.floodlightcontroller.util.DataPathEndpoints;
import net.floodlightcontroller.util.FlowEntry;
+import net.floodlightcontroller.util.FlowEntryAction;
import net.floodlightcontroller.util.FlowEntryId;
+import net.floodlightcontroller.util.FlowEntryMatch;
import net.floodlightcontroller.util.FlowEntrySwitchState;
import net.floodlightcontroller.util.FlowEntryUserState;
import net.floodlightcontroller.util.FlowId;
import net.floodlightcontroller.util.FlowPath;
+import net.floodlightcontroller.util.IPv4Net;
+import net.floodlightcontroller.util.MACAddress;
import net.floodlightcontroller.util.OFMessageDamper;
import net.floodlightcontroller.util.Port;
import net.onrc.onos.util.GraphDBConnection;
@@ -42,6 +46,7 @@
import org.openflow.protocol.OFFlowMod;
import org.openflow.protocol.OFMatch;
import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPort;
import org.openflow.protocol.OFType;
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.action.OFActionOutput;
@@ -58,10 +63,15 @@
protected OFMessageDamper messageDamper;
- protected static int OFMESSAGE_DAMPER_CAPACITY = 50000; // TODO: find sweet spot
- protected static int OFMESSAGE_DAMPER_TIMEOUT = 250; // ms
- public static short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 0; // infinity
- public static short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0; // infinite
+ //
+ // TODO: Values copied from elsewhere (class LearningSwitch).
+ // The local copy should go away!
+ //
+ protected static final int OFMESSAGE_DAMPER_CAPACITY = 50000; // TODO: find sweet spot
+ protected static final int OFMESSAGE_DAMPER_TIMEOUT = 250; // ms
+ public static final short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 0; // infinity
+ public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0; // infinite
+ public static final short PRIORITY_DEFAULT = 100;
/** The logger. */
private static Logger log = LoggerFactory.getLogger(FlowManager.class);
@@ -123,23 +133,69 @@
continue;
}
+ //
+ // Fetch the match conditions
+ //
OFMatch match = new OFMatch();
- match.setInputPort(flowEntryObj.getInPort());
+ match.setWildcards(OFMatch.OFPFW_ALL);
+ Short matchInPort = flowEntryObj.getMatchInPort();
+ if (matchInPort != null) {
+ match.setInputPort(matchInPort);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
+ }
+ Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null) {
+ match.setDataLayerType(matchEthernetFrameType);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+ }
+ String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null) {
+ match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
+ }
+ String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null) {
+ match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
+ }
+ String matchSrcMac = flowEntryObj.getMatchSrcMac();
+ if (matchSrcMac != null) {
+ match.setDataLayerSource(matchSrcMac);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
+ }
+ String matchDstMac = flowEntryObj.getMatchDstMac();
+ if (matchDstMac != null) {
+ match.setDataLayerDestination(matchDstMac);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
+ }
- OFActionOutput action = new OFActionOutput();
- action.setMaxLength((short)0xffff);
- action.setPort(flowEntryObj.getOutPort());
+ //
+ // Fetch the actions
+ //
List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(action);
+ Short actionOutputPort = flowEntryObj.getActionOutput();
+ if (actionOutputPort != null) {
+ OFActionOutput action = new OFActionOutput();
+ // XXX: The max length is hard-coded for now
+ action.setMaxLength((short)0xffff);
+ action.setPort(actionOutputPort);
+ actions.add(action);
+ }
fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
.setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
+ .setPriority(PRIORITY_DEFAULT)
.setBufferId(OFPacketOut.BUFFER_ID_NONE)
.setCookie(cookie)
.setCommand(flowModCommand)
.setMatch(match)
.setActions(actions)
.setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+ fm.setOutPort(OFPort.OFPP_NONE.getValue());
+ if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
+ (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
+ if (actionOutputPort != null)
+ fm.setOutPort(actionOutputPort);
+ }
+
//
// TODO: Set the following flag
// fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
@@ -351,15 +407,35 @@
// - flowEntry.flowEntryMatch()
// - flowEntry.flowEntryActions()
// - flowEntry.dpid()
- // - flowEntry.inPort()
- // - flowEntry.outPort()
// - flowEntry.flowEntryUserState()
// - flowEntry.flowEntrySwitchState()
// - flowEntry.flowEntryErrorState()
+ // - flowEntry.matchInPort()
+ // - flowEntry.matchEthernetFrameType()
+ // - flowEntry.matchSrcIPv4Net()
+ // - flowEntry.matchDstIPv4Net()
+ // - flowEntry.matchSrcMac()
+ // - flowEntry.matchDstMac()
+ // - flowEntry.actionOutput()
//
flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
- flowEntryObj.setInPort(flowEntry.inPort().value());
- flowEntryObj.setOutPort(flowEntry.outPort().value());
+ if (flowEntry.flowEntryMatch().matchInPort())
+ flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+ if (flowEntry.flowEntryMatch().matchEthernetFrameType())
+ flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+ if (flowEntry.flowEntryMatch().matchSrcIPv4Net())
+ flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+ if (flowEntry.flowEntryMatch().matchDstIPv4Net())
+ flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+ if (flowEntry.flowEntryMatch().matchSrcMac())
+ flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+ if (flowEntry.flowEntryMatch().matchDstMac())
+ flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+
+ for (FlowEntryAction fa : flowEntry.flowEntryActions()) {
+ if (fa.actionOutput() != null)
+ flowEntryObj.setActionOutput(fa.actionOutput().port().value());
+ }
// TODO: Hacks with hard-coded state names!
if (found)
flowEntryObj.setUserState("FE_USER_MODIFY");
@@ -640,8 +716,43 @@
FlowEntry flowEntry = new FlowEntry();
flowEntry.setFlowEntryId(new FlowEntryId(flowEntryObj.getFlowEntryId()));
flowEntry.setDpid(new Dpid(flowEntryObj.getSwitchDpid()));
- flowEntry.setInPort(new Port(flowEntryObj.getInPort()));
- flowEntry.setOutPort(new Port(flowEntryObj.getOutPort()));
+
+ //
+ // Extract the match conditions
+ //
+ FlowEntryMatch match = new FlowEntryMatch();
+ Short matchInPort = flowEntryObj.getMatchInPort();
+ if (matchInPort != null)
+ match.enableInPort(new Port(matchInPort));
+ Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null)
+ match.enableEthernetFrameType(matchEthernetFrameType);
+ String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null)
+ match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+ String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null)
+ match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+ String matchSrcMac = flowEntryObj.getMatchSrcMac();
+ if (matchSrcMac != null)
+ match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
+ String matchDstMac = flowEntryObj.getMatchDstMac();
+ if (matchDstMac != null)
+ match.enableDstMac(MACAddress.valueOf(matchDstMac));
+ flowEntry.setFlowEntryMatch(match);
+
+ //
+ // Extract the actions
+ //
+ ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
+ Short actionOutputPort = flowEntryObj.getActionOutput();
+ if (actionOutputPort != null) {
+ FlowEntryAction action = new FlowEntryAction();
+ action.setActionOutput(new Port(actionOutputPort));
+ actions.add(action);
+ }
+ flowEntry.setFlowEntryActions(actions);
+
String userState = flowEntryObj.getUserState();
flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
String switchState = flowEntryObj.getSwitchState();
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
index 304bb5c..1fc1783 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
@@ -54,6 +54,15 @@
// if the port is set to PORT_CONTROLLER
/**
+ * Default constructor.
+ */
+ public ActionOutput() {
+ this.port = null;
+ this.maxLen = 0;
+ }
+
+
+ /**
* Constructor for a given output port and maximum length.
*
* @param port the output port to set.
@@ -66,6 +75,16 @@
}
/**
+ * Constructor for a given output port.
+ *
+ * @param port the output port to set.
+ */
+ public ActionOutput(Port port) {
+ this.port = port;
+ this.maxLen = 0;
+ }
+
+ /**
* Get the output port.
*
* @return the output port.
@@ -113,11 +132,18 @@
private short vlanId; // The VLAN ID to set
/**
+ * Default constructor.
+ */
+ public ActionSetVlanId() {
+ this.vlanId = 0;
+ }
+
+ /**
* Constructor for a given VLAN ID.
*
* @param vlanId the VLAN ID to set.
*/
- ActionSetVlanId(short vlanId) {
+ public ActionSetVlanId(short vlanId) {
this.vlanId = vlanId;
}
@@ -156,11 +182,18 @@
private byte vlanPriority; // The VLAN priority to set
/**
+ * Default constructor.
+ */
+ public ActionSetVlanPriority() {
+ this.vlanPriority = 0;
+ }
+
+ /**
* Constructor for a given VLAN priority.
*
* @param vlanPriority the VLAN priority to set.
*/
- ActionSetVlanPriority(byte vlanPriority) {
+ public ActionSetVlanPriority(byte vlanPriority) {
this.vlanPriority = vlanPriority;
}
@@ -199,11 +232,18 @@
private boolean stripVlan; // If true, strip the VLAN header
/**
+ * Default constructor.
+ */
+ public ActionStripVlan() {
+ this.stripVlan = false;
+ }
+
+ /**
* Constructor for a given boolean flag.
*
* @param stripVlan if true, strip the VLAN header.
*/
- ActionStripVlan(boolean stripVlan) {
+ public ActionStripVlan(boolean stripVlan) {
this.stripVlan = stripVlan;
}
@@ -243,11 +283,18 @@
private MACAddress addr; // The MAC address to set
/**
+ * Default constructor.
+ */
+ public ActionSetEthernetAddr() {
+ this.addr = null;
+ }
+
+ /**
* Constructor for a given MAC address.
*
* @param addr the MAC address to set.
*/
- ActionSetEthernetAddr(MACAddress addr) {
+ public ActionSetEthernetAddr(MACAddress addr) {
this.addr = addr;
}
@@ -287,11 +334,18 @@
private IPv4 addr; // The IPv4 address to set
/**
+ * Default constructor.
+ */
+ public ActionSetIPv4Addr() {
+ this.addr = null;
+ }
+
+ /**
* Constructor for a given IPv4 address.
*
* @param addr the IPv4 address to set.
*/
- ActionSetIPv4Addr(IPv4 addr) {
+ public ActionSetIPv4Addr(IPv4 addr) {
this.addr = addr;
}
@@ -331,11 +385,18 @@
private byte ipToS; // The IP ToS to set DSCP field, 6 bits)
/**
+ * Default constructor.
+ */
+ public ActionSetIpToS() {
+ this.ipToS = 0;
+ }
+
+ /**
* Constructor for a given IP ToS (DSCP field, 6 bits).
*
* @param ipToS the IP ToS (DSCP field, 6 bits) to set.
*/
- ActionSetIpToS(byte ipToS) {
+ public ActionSetIpToS(byte ipToS) {
this.ipToS = ipToS;
}
@@ -375,11 +436,18 @@
private short port; // The TCP/UDP port to set
/**
+ * Default constructor.
+ */
+ public ActionSetTcpUdpPort() {
+ this.port = 0;
+ }
+
+ /**
* Constructor for a given TCP/UDP port.
*
* @param port the TCP/UDP port to set.
*/
- ActionSetTcpUdpPort(short port) {
+ public ActionSetTcpUdpPort(short port) {
this.port = port;
}
@@ -421,6 +489,14 @@
private int queueId; // Where to enqueue the packets
/**
+ * Default constructor.
+ */
+ public ActionEnqueue() {
+ this.port = null;
+ this.queueId = 0;
+ }
+
+ /**
* Constructor for a given port and queue ID.
*
* @param port the port to set.
@@ -515,11 +591,21 @@
/**
* Set the output action on a port.
*
- * @param port the output port to set.
+ * @param action the action to set.
*/
@JsonProperty("actionOutput")
+ public void setActionOutput(ActionOutput action) {
+ actionOutput = action;
+ actionType = ActionValues.ACTION_OUTPUT;
+ }
+
+ /**
+ * Set the output action on a port.
+ *
+ * @param port the output port to set.
+ */
public void setActionOutput(Port port) {
- actionOutput = new ActionOutput(port, (short)0);
+ actionOutput = new ActionOutput(port);
actionType = ActionValues.ACTION_OUTPUT;
}
@@ -528,7 +614,6 @@
*
* @param maxLen the maximum length (in bytes) to send to controller.
*/
- @JsonProperty("actionOutputToController")
public void setActionOutputToController(short maxLen) {
Port port = new Port(Port.PortValues.PORT_CONTROLLER);
actionOutput = new ActionOutput(port, maxLen);
@@ -546,9 +631,19 @@
/**
* Set the action to set the VLAN ID.
*
- * @param vlanId the VLAN ID to set.
+ * @param action the action to set.
*/
@JsonProperty("actionSetVlanId")
+ public void setActionSetVlanId(ActionSetVlanId action) {
+ actionSetVlanId = action;
+ actionType = ActionValues.ACTION_SET_VLAN_VID;
+ }
+
+ /**
+ * Set the action to set the VLAN ID.
+ *
+ * @param vlanId the VLAN ID to set.
+ */
public void setActionSetVlanId(short vlanId) {
actionSetVlanId = new ActionSetVlanId(vlanId);
actionType = ActionValues.ACTION_SET_VLAN_VID;
@@ -567,9 +662,19 @@
/**
* Set the action to set the VLAN priority.
*
- * @param vlanPriority the VLAN priority to set.
+ * @param action the action to set.
*/
@JsonProperty("actionSetVlanPriority")
+ public void setActionSetVlanPriority(ActionSetVlanPriority action) {
+ actionSetVlanPriority = action;
+ actionType = ActionValues.ACTION_SET_VLAN_PCP;
+ }
+
+ /**
+ * Set the action to set the VLAN priority.
+ *
+ * @param vlanPriority the VLAN priority to set.
+ */
public void setActionSetVlanPriority(byte vlanPriority) {
actionSetVlanPriority = new ActionSetVlanPriority(vlanPriority);
actionType = ActionValues.ACTION_SET_VLAN_PCP;
@@ -588,9 +693,19 @@
/**
* Set the action to strip the VLAN header.
*
- * @param stripVlan if true, strip the VLAN header.
+ * @param action the action to set.
*/
@JsonProperty("actionStripVlan")
+ public void setActionStripVlan(ActionStripVlan action) {
+ actionStripVlan = action;
+ actionType = ActionValues.ACTION_STRIP_VLAN;
+ }
+
+ /**
+ * Set the action to strip the VLAN header.
+ *
+ * @param stripVlan if true, strip the VLAN header.
+ */
public void setActionStripVlan(boolean stripVlan) {
actionStripVlan = new ActionStripVlan(stripVlan);
actionType = ActionValues.ACTION_STRIP_VLAN;
@@ -609,9 +724,19 @@
/**
* Set the action to set the Ethernet source address.
*
- * @param addr the MAC address to set as the Ethernet source address.
+ * @param action the action to set.
*/
@JsonProperty("actionSetEthernetSrcAddr")
+ public void setActionSetEthernetSrcAddr(ActionSetEthernetAddr action) {
+ actionSetEthernetSrcAddr = action;
+ actionType = ActionValues.ACTION_SET_DL_SRC;
+ }
+
+ /**
+ * Set the action to set the Ethernet source address.
+ *
+ * @param addr the MAC address to set as the Ethernet source address.
+ */
public void setActionSetEthernetSrcAddr(MACAddress addr) {
actionSetEthernetSrcAddr = new ActionSetEthernetAddr(addr);
actionType = ActionValues.ACTION_SET_DL_SRC;
@@ -630,9 +755,19 @@
/**
* Set the action to set the Ethernet destination address.
*
- * @param addr the MAC address to set as the Ethernet destination address.
+ * @param action the action to set.
*/
@JsonProperty("actionSetEthernetDstAddr")
+ public void setActionSetEthernetDstAddr(ActionSetEthernetAddr action) {
+ actionSetEthernetDstAddr = action;
+ actionType = ActionValues.ACTION_SET_DL_DST;
+ }
+
+ /**
+ * Set the action to set the Ethernet destination address.
+ *
+ * @param addr the MAC address to set as the Ethernet destination address.
+ */
public void setActionSetEthernetDstAddr(MACAddress addr) {
actionSetEthernetDstAddr = new ActionSetEthernetAddr(addr);
actionType = ActionValues.ACTION_SET_DL_DST;
@@ -651,9 +786,19 @@
/**
* Set the action to set the IPv4 source address.
*
- * @param addr the IPv4 address to set as the IPv4 source address.
+ * @param action the action to set.
*/
@JsonProperty("actionSetIPv4SrcAddr")
+ public void setActionSetIPv4SrcAddr(ActionSetIPv4Addr action) {
+ actionSetIPv4SrcAddr = action;
+ actionType = ActionValues.ACTION_SET_NW_SRC;
+ }
+
+ /**
+ * Set the action to set the IPv4 source address.
+ *
+ * @param addr the IPv4 address to set as the IPv4 source address.
+ */
public void setActionSetIPv4SrcAddr(IPv4 addr) {
actionSetIPv4SrcAddr = new ActionSetIPv4Addr(addr);
actionType = ActionValues.ACTION_SET_NW_SRC;
@@ -672,9 +817,19 @@
/**
* Set the action to set the IPv4 destination address.
*
- * @param addr the IPv4 address to set as the IPv4 destination address.
+ * @param action the action to set.
*/
@JsonProperty("actionSetIPv4DstAddr")
+ public void setActionSetIPv4DstAddr(ActionSetIPv4Addr action) {
+ actionSetIPv4DstAddr = action;
+ actionType = ActionValues.ACTION_SET_NW_DST;
+ }
+
+ /**
+ * Set the action to set the IPv4 destination address.
+ *
+ * @param addr the IPv4 address to set as the IPv4 destination address.
+ */
public void setActionSetIPv4DstAddr(IPv4 addr) {
actionSetIPv4DstAddr = new ActionSetIPv4Addr(addr);
actionType = ActionValues.ACTION_SET_NW_DST;
@@ -693,9 +848,19 @@
/**
* Set the action to set the IP ToS (DSCP field, 6 bits).
*
- * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+ * @param action the action to set.
*/
@JsonProperty("actionSetIpToS")
+ public void setActionSetIpToS(ActionSetIpToS action) {
+ actionSetIpToS = action;
+ actionType = ActionValues.ACTION_SET_NW_TOS;
+ }
+
+ /**
+ * Set the action to set the IP ToS (DSCP field, 6 bits).
+ *
+ * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+ */
public void setActionSetIpToS(byte ipToS) {
actionSetIpToS = new ActionSetIpToS(ipToS);
actionType = ActionValues.ACTION_SET_NW_TOS;
@@ -714,9 +879,19 @@
/**
* Set the action to set the TCP/UDP source port.
*
- * @param port the TCP/UDP port to set as the TCP/UDP source port.
+ * @param action the action to set.
*/
@JsonProperty("actionSetTcpUdpSrcPort")
+ public void setActionSetTcpUdpSrcPort(ActionSetTcpUdpPort action) {
+ actionSetTcpUdpSrcPort = action;
+ actionType = ActionValues.ACTION_SET_TP_SRC;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP source port.
+ *
+ * @param port the TCP/UDP port to set as the TCP/UDP source port.
+ */
public void setActionSetTcpUdpSrcPort(short port) {
actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(port);
actionType = ActionValues.ACTION_SET_TP_SRC;
@@ -735,9 +910,19 @@
/**
* Set the action to set the TCP/UDP destination port.
*
- * @param port the TCP/UDP port to set as the TCP/UDP destination port.
+ * @param action the action to set.
*/
@JsonProperty("actionSetTcpUdpDstPort")
+ public void setActionSetTcpUdpDstPort(ActionSetTcpUdpPort action) {
+ actionSetTcpUdpDstPort = action;
+ actionType = ActionValues.ACTION_SET_TP_DST;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP destination port.
+ *
+ * @param port the TCP/UDP port to set as the TCP/UDP destination port.
+ */
public void setActionSetTcpUdpDstPort(short port) {
actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(port);
actionType = ActionValues.ACTION_SET_TP_DST;
@@ -754,10 +939,20 @@
/**
* Set the action to output to queue on a port.
*
+ * @param action the action to set.
+ */
+ @JsonProperty("actionEnqueue")
+ public void setActionEnqueue(ActionEnqueue action) {
+ actionEnqueue = action;
+ actionType = ActionValues.ACTION_ENQUEUE;
+ }
+
+ /**
+ * Set the action to output to queue on a port.
+ *
* @param port the port to set.
* @param int queueId the queue ID to set.
*/
- @JsonProperty("actionEnqueue")
public void setActionEnqueue(Port port, int queueId) {
actionEnqueue = new ActionEnqueue(port, queueId);
actionType = ActionValues.ACTION_ENQUEUE;
diff --git a/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java b/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
index afd9dc6..dadee65 100644
--- a/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
+++ b/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
@@ -6,6 +6,23 @@
import net.floodlightcontroller.core.module.IFloodlightService;
+/**
+ * A registry service that allows ONOS to register controllers and switches
+ * in a way that is global to the entire ONOS cluster. The registry is the
+ * arbiter for allowing controllers to control switches.
+ *
+ * The OVS/OF1.{2,3} fault tolerance model is a switch connects to multiple
+ * controllers, and the controllers send role requests to determine what their
+ * role is in controlling the switch.
+ *
+ * The ONOS fault tolerance model allows only a single controller to have
+ * control of a switch (MASTER role) at once. Controllers therefore need a
+ * mechanism that enables them to decide who should control a each switch.
+ * The registry service provides this mechanism.
+ *
+ * @author jono
+ *
+ */
public interface IControllerRegistryService extends IFloodlightService {
/**
@@ -54,19 +71,11 @@
*/
public boolean hasControl(long dpid);
-
- /**
- * Superseded by registerController
- * @param id
- */
- @Deprecated
- public void setMastershipId (String id);
-
/**
* Get the unique ID used to identify this controller in the cluster
* @return
*/
- public String getMastershipId ();
+ public String getControllerId ();
/**
* Register a controller to the ONOS cluster. Must be called before
@@ -92,7 +101,18 @@
*/
public Map<String, List<ControllerRegistryEntry>> getAllSwitches();
+ /**
+ * Get the controller that has control of a given switch
+ * @param dpid Switch to find controller for
+ * @return controller ID
+ * @throws RegistryException Errors contacting registry service
+ */
public String getControllerForSwitch(long dpid) throws RegistryException;
+ /**
+ * Get all switches controlled by a given controller
+ * @param controllerId
+ * @return Collection of dpids
+ */
public Collection<Long> getSwitchesControlledByController(String controllerId);
}
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 8a468bc..7345084 100644
--- a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
@@ -16,14 +16,19 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * Implementation of a registry that doesn't rely on any external registry
+ * service. This is designed to be used only in single-node setups (e.g. for
+ * development). All registry data is stored in local memory.
+ * @author jono
+ *
+ */
public class StandaloneRegistry implements IFloodlightModule,
IControllerRegistryService {
protected static Logger log = LoggerFactory.getLogger(StandaloneRegistry.class);
protected IRestApiService restApi;
- //protected String controllerId;
-
protected String controllerId = null;
protected Map<String, ControlChangeCallback> switchCallbacks;
@@ -63,13 +68,7 @@
}
@Override
- public void setMastershipId(String id) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public String getMastershipId() {
+ public String getControllerId() {
return controllerId;
}
@@ -147,16 +146,6 @@
restApi = context.getServiceImpl(IRestApiService.class);
switchCallbacks = new HashMap<String, ControlChangeCallback>();
-
- //Put some data in for testing
- /*
- try {
- registerController("hurro");
- requestControl(2L, null);
- } catch (RegistryException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }*/
}
@Override
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 468bb07..025bbfe 100644
--- a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
@@ -36,6 +36,12 @@
import com.netflix.curator.framework.recipes.leader.Participant;
import com.netflix.curator.retry.ExponentialBackoffRetry;
+/**
+ * A registry service that uses Zookeeper. All data is stored in Zookeeper,
+ * so this can be used as a global registry in a multi-node ONOS cluster.
+ * @author jono
+ *
+ */
public class ZookeeperRegistry implements IFloodlightModule, IControllerRegistryService {
protected static Logger log = LoggerFactory.getLogger(ZookeeperRegistry.class);
@@ -43,10 +49,9 @@
protected IRestApiService restApi;
- //TODO read this from configuration
+ //This is the default, it's overwritten by the connectionString configuration parameter
protected String connectionString = "localhost:2181";
-
private final String namespace = "onos";
private final String switchLatchesPath = "/switches";
private final String controllerPath = "/controllers";
@@ -64,6 +69,19 @@
protected static final int sessionTimeout = 2000;
protected static final int connectionTimeout = 4000;
+ /**
+ * Watches for changes in switch leadership election. The Curator
+ * LeaderLatch doesn't notify us when leadership changes so we set a watch
+ * on the election znodes to get leadership change events. The process
+ * method will be called whenever the switches children change in
+ * Zookeeper. We then have to work out whether to send a control-changed
+ * event to our clients and reset the watch.
+ *
+ * TODO I think it's possible to miss events that happen while we're
+ * processing the watch and before we've set a new watch. Need to think
+ * of a safer way to implement leader change notifications.
+ *
+ */
protected class ParamaterizedCuratorWatcher implements CuratorWatcher {
private String dpid;
private boolean isLeader = false;
@@ -78,7 +96,6 @@
public synchronized void process(WatchedEvent event) throws Exception {
log.debug("Watch Event: {}", event);
- LeaderLatch latch = switchLatches.get(dpid);
if (event.getState() == KeeperState.Disconnected){
if (isLeader) {
@@ -92,6 +109,14 @@
}
}
return;
+ //TODO Watcher is never reset once we reconnect to Zookeeper
+ }
+
+ LeaderLatch latch = switchLatches.get(dpid);
+ if (latch == null){
+ log.debug("In watcher process, looks like control was released for {}",
+ dpid);
+ return;
}
try {
@@ -112,24 +137,24 @@
}
} catch (Exception e){
if (isLeader){
- log.debug("Exception checking leadership status. Assume leadship lost for {}",
+ log.debug("Exception checking leadership status. Assume leadership lost for {}",
dpid);
isLeader = false;
switchCallbacks.get(dpid).controlChanged(HexString.toLong(dpid), false);
}
+ } finally {
+ client.getChildren().usingWatcher(this).inBackground().forPath(latchPath);
}
-
- client.getChildren().usingWatcher(this).inBackground().forPath(latchPath);
//client.getChildren().usingWatcher(this).forPath(latchPath);
}
}
- /*
- * Listens for changes to the switch znodes in Zookeeper. This maintains the second level of
- * PathChildrenCaches that hold the controllers contending for each switch - there's one for
- * each switch.
+ /**
+ * Listens for changes to the switch znodes in Zookeeper. This maintains
+ * the second level of PathChildrenCaches that hold the controllers
+ * contending for each switch - there's one for each switch.
*/
PathChildrenCacheListener switchPathCacheListener = new PathChildrenCacheListener() {
@Override
@@ -173,6 +198,7 @@
@Override
public void requestControl(long dpid, ControlChangeCallback cb) throws RegistryException {
+ log.info("Requesting control for {}", HexString.toHexString(dpid));
if (controllerId == null){
throw new RuntimeException("Must register a controller before calling requestControl");
@@ -182,8 +208,10 @@
String latchPath = switchLatchesPath + "/" + dpidStr;
if (switchLatches.get(dpidStr) != null){
- throw new RuntimeException("Leader election for switch " + dpidStr +
- "is already running");
+ //throw new RuntimeException("Leader election for switch " + dpidStr +
+ // "is already running");
+ log.debug("Already contesting {}, returning", HexString.toHexString(dpid));
+ return;
}
LeaderLatch latch = new LeaderLatch(client, latchPath, controllerId);
@@ -205,20 +233,21 @@
@Override
public void releaseControl(long dpid) {
+ log.info("Releasing control for {}", HexString.toHexString(dpid));
String dpidStr = HexString.toHexString(dpid);
LeaderLatch latch = switchLatches.get(dpidStr);
if (latch == null) {
- log.debug("Trying to release mastership for switch we are not contesting");
+ log.debug("Trying to release control of a switch we are not contesting");
return;
}
try {
latch.close();
} catch (IOException e) {
- //I think it's OK not to do anything here. Either the node got deleted correctly,
- //or the connection went down and the node got deleted.
+ //I think it's OK not to do anything here. Either the node got
+ //deleted correctly, or the connection went down and the node got deleted.
} finally {
switchLatches.remove(dpidStr);
switchCallbacks.remove(dpidStr);
@@ -244,13 +273,7 @@
}
@Override
- public void setMastershipId(String id) {
- //TODO remove this method if not needed
- //controllerId = id;
- }
-
- @Override
- public String getMastershipId() {
+ public String getControllerId() {
return controllerId;
}
@@ -423,8 +446,8 @@
//Don't prime the cache, we want a notification for each child node in the path
switchCache.start(StartMode.NORMAL);
} catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ throw new FloodlightModuleException("Error initialising ZookeeperRegistry: "
+ + e.getMessage());
}
}
@@ -432,5 +455,4 @@
public void startUp (FloodlightModuleContext context) {
restApi.addRestletRoutable(new RegistryWebRoutable());
}
-
}
diff --git a/src/main/java/org/openflow/protocol/OFMatch.java b/src/main/java/org/openflow/protocol/OFMatch.java
index 0336d7d..397263d 100644
--- a/src/main/java/org/openflow/protocol/OFMatch.java
+++ b/src/main/java/org/openflow/protocol/OFMatch.java
@@ -911,7 +911,7 @@
* one of STR_NW_DST or STR_NW_SRC
* @throws IllegalArgumentException
*/
- private void setFromCIDR(String cidr, String which)
+ public void setFromCIDR(String cidr, String which)
throws IllegalArgumentException {
String values[] = cidr.split("/");
String[] ip_str = values[0].split("\\.");
diff --git a/start-onos.sh b/start-onos.sh
index f8e9309..012a994 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -78,7 +78,7 @@
# Run floodlight
echo "Starting ONOS controller ..."
echo
- java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf ./onos.properties > /dev/null 2>&1 &
+ java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf ${FL_HOME}/onos.properties > /dev/null 2>&1 &
# echo "java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf ./onos.properties > /dev/null 2>&1 &"
sudo -b /usr/sbin/tcpdump -n -i eth0 -s0 -w ${PCAP_LOG} 'tcp port 6633' > /dev/null 2>&1
}
diff --git a/test-network/mininet/net.sprint5-templete.py b/test-network/mininet/net.sprint5-templete.py
new file mode 100755
index 0000000..0fc96f1
--- /dev/null
+++ b/test-network/mininet/net.sprint5-templete.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python
+
+NWID=1
+NR_NODES=20
+#Controllers=[{"ip":'127.0.0.1', "port":6633}, {"ip":'10.0.1.28', "port":6633}]
+Controllers=[{"ip":'10.0.1.28', "port":6633}]
+
+"""
+Start up a Simple topology
+"""
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController
+from mininet.log import setLogLevel, info, error, warn, debug
+from mininet.cli import CLI
+from mininet.topo import Topo
+from mininet.util import quietRun
+from mininet.moduledeps import pathCheck
+from mininet.link import Link, TCLink
+
+from sys import exit
+import os.path
+from subprocess import Popen, STDOUT, PIPE
+
+import sys
+
+#import argparse
+
+class MyController( Controller ):
+ def __init__( self, name, ip='127.0.0.1', port=6633, **kwargs):
+ """Init.
+ name: name to give controller
+ ip: the IP address where the remote controller is
+ listening
+ port: the port where the remote controller is listening"""
+ Controller.__init__( self, name, ip=ip, port=port, **kwargs )
+
+ def start( self ):
+ "Overridden to do nothing."
+ return
+
+ def stop( self ):
+ "Overridden to do nothing."
+ return
+
+ def checkListening( self ):
+ "Warn if remote controller is not accessible"
+ listening = self.cmd( "echo A | telnet -e A %s %d" %
+ ( self.ip, self.port ) )
+ if 'Unable' in listening:
+ warn( "Unable to contact the remote controller"
+ " at %s:%d\n" % ( self.ip, self.port ) )
+
+class SDNTopo( Topo ):
+ "SDN Topology"
+
+ def __init__( self, *args, **kwargs ):
+ Topo.__init__( self, *args, **kwargs )
+
+ switch = []
+ host = []
+ root = []
+
+ for i in range (NR_NODES):
+ name_suffix = '%02d' % NWID + "." + '%02d' % i
+ dpid_suffix = '%02x' % NWID + '%02x' % i
+ dpid = '0000' + '0000' + '0000' + dpid_suffix
+ sw = self.addSwitch('sw'+name_suffix, dpid=dpid)
+ switch.append(sw)
+
+ for i in range (NR_NODES):
+ host.append(self.addHost( 'host%d' % i ))
+
+ for i in range (NR_NODES):
+ root.append(self.addHost( 'root%d' % i, inNamespace=False ))
+
+ for i in range (NR_NODES):
+ self.addLink(host[i], switch[i])
+
+ for i in range (1, NR_NODES):
+ self.addLink(switch[0], switch[i])
+
+ for i in range (NR_NODES):
+ self.addLink(root[i], host[i])
+
+def startsshd( host ):
+ "Start sshd on host"
+ info( '*** Starting sshd\n' )
+ name, intf, ip = host.name, host.defaultIntf(), host.IP()
+ banner = '/tmp/%s.banner' % name
+ host.cmd( 'echo "Welcome to %s at %s" > %s' % ( name, ip, banner ) )
+ host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
+ info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
+
+def startsshds ( hosts ):
+ for h in hosts:
+ startsshd( h )
+
+def stopsshd( ):
+ "Stop *all* sshd processes with a custom banner"
+ info( '*** Shutting down stale sshd/Banner processes ',
+ quietRun( "pkill -9 -f Banner" ), '\n' )
+
+def sdnnet(opt):
+ topo = SDNTopo()
+ info( '*** Creating network\n' )
+ #net = Mininet( topo=topo, controller=MyController, link=TCLink)
+ net = Mininet( topo=topo, link=TCLink, build=False)
+ controllers=[]
+ for c in Controllers:
+ rc = RemoteController('c%d' % Controllers.index(c), ip=c['ip'],port=c['port'])
+ print "controller ip %s port %s" % (c['ip'], c['port'])
+ controllers.append(rc)
+
+ net.controllers=controllers
+ net.build()
+
+ host = []
+ for i in range (NR_NODES):
+ host.append(net.get( 'host%d' % i ))
+
+ net.start()
+
+ sw=net.get('sw01.00')
+ print "center sw", sw
+ sw.attach('tapa0')
+
+ for i in range (NR_NODES):
+ host[i].defaultIntf().setIP('192.168.%d.%d/16' % (NWID,i))
+
+ root = []
+ for i in range (NR_NODES):
+ root.append(net.get( 'root%d' % i ))
+
+ for i in range (NR_NODES):
+ host[i].intf('host%d-eth1' % i).setIP('1.1.%d.1/24' % i)
+ root[i].intf('root%d-eth0' % i).setIP('1.1.%d.2/24' % i)
+
+ stopsshd ()
+ startsshds ( host )
+
+ if opt=="cli":
+ CLI(net)
+ stopsshd()
+ net.stop()
+
+if __name__ == '__main__':
+ setLogLevel( 'info' )
+ if len(sys.argv) == 1:
+ sdnnet("cli")
+ elif len(sys.argv) == 2 and sys.argv[1] == "-n":
+ sdnnet("nocli")
+ else:
+ print "%s [-n]" % sys.argv[0]
diff --git a/web/add_flow.py b/web/add_flow.py
index 18846b7..28819c9 100755
--- a/web/add_flow.py
+++ b/web/add_flow.py
@@ -1,6 +1,7 @@
#! /usr/bin/env python
# -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
+import copy
import pprint
import os
import sys
@@ -17,8 +18,9 @@
#
## Global Var ##
-ControllerIP="127.0.0.1"
-ControllerPort=8080
+ControllerIP = "127.0.0.1"
+ControllerPort = 8080
+MonitoringEnabled = False
DEBUG=0
pp = pprint.PrettyPrinter(indent=4)
@@ -67,13 +69,15 @@
inPort = f['inPort']['value'];
outPort = f['outPort']['value'];
dpid = f['dpid']['value']
- print "FlowEntry: (%s, %s, %s)" % (inPort, dpid, outPort)
+ print " FlowEntry: (%s, %s, %s)" % (inPort, dpid, outPort)
return parsedResult
def add_flow_path(flow_path):
+ 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, ControllerIP, ControllerPort)
+ command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/flow/add/json" % (flow_path_json, ControllerIP, ControllerPort)
debug("add_flow_path %s" % command)
result = os.popen(command).read()
debug("result %s" % result)
@@ -83,27 +87,230 @@
log_error("Controller IF has issue")
exit(1)
-if __name__ == "__main__":
- usage_msg = "Usage: %s <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port>" % (sys.argv[0])
+def delete_flow_path(flow_id):
+ command = "curl -s \"http://%s:%s/wm/flow/delete/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
+ debug("delete_flow_path %s" % command)
+ result = os.popen(command).read()
+ debug("result %s" % result)
+ # parsedResult = json.loads(result)
+ # debug("parsed %s" % parsedResult)
- # app.debug = False;
-
- # Usage info
- if len(sys.argv) > 1 and (sys.argv[1] == "-h" or sys.argv[1] == "--help"):
- print(usage_msg)
- exit(0)
-
- # Check arguments
- if len(sys.argv) < 7:
+def extract_flow_args(my_args):
+ # Check the arguments
+ if len(my_args) < 6:
log_error(usage_msg)
exit(1)
- # Do the work
- my_flow_id = sys.argv[1]
- my_installer_id = sys.argv[2]; # 'ONOS-Path-Computation-Python'
- data_path = shortest_path(sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])
+ # Extract the mandatory arguments
+ my_flow_id = my_args[0]
+ my_installer_id = my_args[1]
+ my_src_dpid = my_args[2]
+ my_src_port = my_args[3]
+ my_dst_dpid = my_args[4]
+ my_dst_port = my_args[5]
+
+ #
+ # Extract the "match" and "action" arguments
+ #
+ match = {}
+ matchInPortEnabled = True # NOTE: Enabled by default
+ actions = []
+ actionOutputEnabled = True # NOTE: Enabled by default
+ idx = 6
+ while idx < len(my_args):
+ action = {}
+ arg1 = my_args[idx]
+ idx = idx + 1
+ # Extract the second argument
+ if idx >= len(my_args):
+ error_arg = "ERROR: Missing or invalid '" + arg1 + "' argument"
+ log_error(error_arg)
+ log_error(usage_msg)
+ exit(1)
+ arg2 = my_args[idx]
+ idx = idx + 1
+
+ if arg1 == "matchInPort":
+ # Just mark whether inPort matching is enabled
+ matchInPortEnabled = arg2 in ['True', 'true']
+ # inPort = {}
+ # inPort['value'] = int(arg2, 0)
+ # match['inPort'] = inPort
+ ## match['matchInPort'] = True
+ elif arg1 == "matchSrcMac":
+ srcMac = {}
+ srcMac['value'] = arg2
+ match['srcMac'] = srcMac
+ # match['matchSrcMac'] = True
+ elif arg1 == "matchDstMac":
+ dstMac = {}
+ dstMac['value'] = arg2
+ match['dstMac'] = dstMac
+ # match['matchDstMac'] = True
+ elif arg1 == "matchVlanId":
+ match['vlanId'] = int(arg2, 0)
+ # match['matchVlanId'] = True
+ elif arg1 == "matchVlanPriority":
+ match['vlanPriority'] = int(arg2, 0)
+ # match['matchVlanPriority'] = True
+ elif arg1 == "matchEthernetFrameType":
+ match['ethernetFrameType'] = int(arg2, 0)
+ # match['matchEthernetFrameType'] = True
+ elif arg1 == "matchIpToS":
+ match['ipToS'] = int(arg2, 0)
+ # match['matchIpToS'] = True
+ elif arg1 == "matchIpProto":
+ match['ipProto'] = int(arg2, 0)
+ # match['matchIpProto'] = True
+ elif arg1 == "matchSrcIPv4Net":
+ srcIPv4Net = {}
+ srcIPv4Net['value'] = arg2
+ match['srcIPv4Net'] = srcIPv4Net
+ # match['matchSrcIPv4Net'] = True
+ elif arg1 == "matchDstIPv4Net":
+ dstIPv4Net = {}
+ dstIPv4Net['value'] = arg2
+ match['dstIPv4Net'] = dstIPv4Net
+ # match['matchDstIPv4Net'] = True
+ elif arg1 == "matchSrcTcpUdpPort":
+ match['srcTcpUdpPort'] = int(arg2, 0)
+ # match['matchSrcTcpUdpPort'] = True
+ elif arg1 == "matchDstTcpUdpPort":
+ match['dstTcpUdpPort'] = int(arg2, 0)
+ # match['matchDstTcpUdpPort'] = True
+ elif arg1 == "actionOutput":
+ # Just mark whether ACTION_OUTPUT action is enabled
+ actionOutputEnabled = arg2 in ['True', 'true']
+ #
+ # TODO: Complete the implementation for ACTION_OUTPUT
+ # actionOutput = {}
+ # outPort = {}
+ # outPort['value'] = int(arg2, 0)
+ # actionOutput['port'] = outPort
+ # actionOutput['maxLen'] = int(arg3, 0)
+ # action['actionOutput'] = actionOutput
+ # # action['actionType'] = 'ACTION_OUTPUT'
+ # actions.append(action)
+ #
+ elif arg1 == "actionSetVlanId":
+ vlanId = {}
+ vlanId['vlanId'] = int(arg2, 0)
+ action['actionSetVlanId'] = vlanId
+ # action['actionType'] = 'ACTION_SET_VLAN_VID'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetVlanPriority":
+ vlanPriority = {}
+ vlanPriority['vlanPriority'] = int(arg2, 0)
+ action['actionSetVlanPriority'] = vlanPriority
+ # action['actionType'] = 'ACTION_SET_VLAN_PCP'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetIpToS":
+ ipToS = {}
+ ipToS['ipToS'] = int(arg2, 0)
+ action['actionSetIpToS'] = ipToS
+ # action['actionType'] = 'ACTION_SET_NW_TOS'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetTcpUdpSrcPort":
+ tcpUdpSrcPort = {}
+ tcpUdpSrcPort['port'] = int(arg2, 0)
+ action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
+ # action['actionType'] = 'ACTION_SET_TP_SRC'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetTcpUdpDstPort":
+ tcpUdpDstPort = {}
+ tcpUdpDstPort['port'] = int(arg2, 0)
+ action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
+ # action['actionType'] = 'ACTION_SET_TP_DST'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionStripVlan":
+ stripVlan = {}
+ stripVlan['stripVlan'] = arg2 in ['True', 'true']
+ action['actionStripVlan'] = stripVlan
+ # action['actionType'] = 'ACTION_STRIP_VLAN'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetEthernetSrcAddr":
+ ethernetSrcAddr = {}
+ ethernetSrcAddr['value'] = arg2
+ setEthernetSrcAddr = {}
+ setEthernetSrcAddr['addr'] = ethernetSrcAddr
+ action['actionSetEthernetSrcAddr'] = setEthernetSrcAddr
+ # action['actionType'] = 'ACTION_SET_DL_SRC'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetEthernetDstAddr":
+ ethernetDstAddr = {}
+ ethernetDstAddr['value'] = arg2
+ setEthernetDstAddr = {}
+ setEthernetDstAddr['addr'] = ethernetDstAddr
+ action['actionSetEthernetDstAddr'] = setEthernetDstAddr
+ # action['actionType'] = 'ACTION_SET_DL_DST'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetIPv4SrcAddr":
+ IPv4SrcAddr = {}
+ IPv4SrcAddr['value'] = arg2
+ setIPv4SrcAddr = {}
+ setIPv4SrcAddr['addr'] = IPv4SrcAddr
+ action['actionSetIPv4SrcAddr'] = setIPv4SrcAddr
+ # action['actionType'] = 'ACTION_SET_NW_SRC'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetIPv4DstAddr":
+ IPv4DstAddr = {}
+ IPv4DstAddr['value'] = arg2
+ setIPv4DstAddr = {}
+ setIPv4DstAddr['addr'] = IPv4DstAddr
+ action['actionSetIPv4DstAddr'] = setIPv4DstAddr
+ # action['actionType'] = 'ACTION_SET_NW_DST'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionEnqueue":
+ # TODO: Implement ACTION_ENQUEUE
+ actionEnqueue = {}
+ # actionEnqueue['queueId'] = int(arg2, 0)
+ # enqueuePort = {}
+ # enqueuePort['value'] = int(arg3, 0)
+ # actionEnqueue['port'] = enqueuePort
+ # action['actionEnqueue'] = actionEnqueue
+ # # action['actionType'] = 'ACTION_ENQUEUE'
+ # actions.append(copy.deepcopy(action))
+ #
+ else:
+ log_error("ERROR: Unknown argument '%s'" % (arg1))
+ log_error(usage_msg)
+ exit(1)
+
+ return {
+ 'my_flow_id' : my_flow_id,
+ 'my_installer_id' : my_installer_id,
+ 'my_src_dpid' : my_src_dpid,
+ 'my_src_port' : my_src_port,
+ 'my_dst_dpid' : my_dst_dpid,
+ 'my_dst_port' : my_dst_port,
+ 'match' : match,
+ 'matchInPortEnabled' : matchInPortEnabled,
+ 'actions' : actions,
+ 'actionOutputEnabled' : actionOutputEnabled
+ }
+
+def compute_data_path(parsed_args):
+
+ my_src_dpid = parsed_args['my_src_dpid']
+ my_src_port = parsed_args['my_src_port']
+ my_dst_dpid = parsed_args['my_dst_dpid']
+ my_dst_port = parsed_args['my_dst_port']
+
+ # Compute the shortest path
+ data_path = shortest_path(my_src_dpid, my_src_port, my_dst_dpid, my_dst_port)
debug("Data Path: %s" % data_path)
+ return data_path
+
+def compute_flow_path(parsed_args, data_path):
+
+ my_flow_id = parsed_args['my_flow_id']
+ my_installer_id = parsed_args['my_installer_id']
+ match = parsed_args['match']
+ matchInPortEnabled = parsed_args['matchInPortEnabled']
+ actions = parsed_args['actions']
+ actionOutputEnabled = parsed_args['actionOutputEnabled']
+ my_data_path = copy.deepcopy(data_path)
flow_id = {}
flow_id['value'] = my_flow_id
@@ -113,9 +320,121 @@
flow_path = {}
flow_path['flowId'] = flow_id
flow_path['installerId'] = installer_id
- flow_path['dataPath'] = data_path
- flow_path_json = json.dumps(flow_path)
- debug("Flow Path: %s" % flow_path_json)
+ #
+ # Add the match conditions to each flow entry
+ #
+ if (len(match) > 0) or matchInPortEnabled:
+ idx = 0
+ while idx < len(my_data_path['flowEntries']):
+ if matchInPortEnabled:
+ inPort = my_data_path['flowEntries'][idx]['inPort']
+ match['inPort'] = copy.deepcopy(inPort)
+ # match['matchInPort'] = True
+ my_data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
+ idx = idx + 1
- add_flow_path(flow_path_json)
+ #
+ # Set the actions for each flow entry
+ # NOTE: The actions from the command line are aplied
+ # ONLY to the first flow entry.
+ #
+ # If ACTION_OUTPUT action is enabled, then apply it
+ # to each flow entry.
+ #
+ if (len(actions) > 0) or actionOutputEnabled:
+ idx = 0
+ while idx < len(my_data_path['flowEntries']):
+ if idx > 0:
+ actions = [] # Reset the actions for all but first entry
+ action = {}
+ outPort = my_data_path['flowEntries'][idx]['outPort']
+ actionOutput = {}
+ actionOutput['port'] = copy.deepcopy(outPort)
+ # actionOutput['maxLen'] = 0 # TODO: not used for now
+ action['actionOutput'] = copy.deepcopy(actionOutput)
+ # action['actionType'] = 'ACTION_OUTPUT'
+ actions.append(copy.deepcopy(action))
+
+ my_data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
+ idx = idx + 1
+
+
+ flow_path['dataPath'] = my_data_path
+ debug("Flow Path: %s" % flow_path)
+
+ add_flow_path(flow_path)
+
+
+if __name__ == "__main__":
+ usage_msg = "Usage: %s [Flags] <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Match Conditions] [Actions]\n" % (sys.argv[0])
+ usage_msg = usage_msg + " Flags:\n"
+ usage_msg = usage_msg + " -m Monitor and maintain the installed shortest path\n"
+ usage_msg = usage_msg + " Match Conditions:\n"
+ usage_msg = usage_msg + " matchInPort <True|False> (default to True)\n"
+ usage_msg = usage_msg + " matchSrcMac <source MAC address>\n"
+ usage_msg = usage_msg + " matchDstMac <destination MAC address>\n"
+ usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
+ usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
+ usage_msg = usage_msg + " matchEthernetFrameType <Ethernet frame type>\n"
+
+ usage_msg = usage_msg + " Match Conditions (not implemented yet):\n"
+ usage_msg = usage_msg + " matchVlanId <VLAN ID>\n"
+ usage_msg = usage_msg + " matchVlanPriority <VLAN priority>\n"
+ usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
+ usage_msg = usage_msg + " matchIpProto <IP protocol>\n"
+ usage_msg = usage_msg + " matchSrcTcpUdpPort <source TCP/UDP port>\n"
+ usage_msg = usage_msg + " matchDstTcpUdpPort <destination TCP/UDP port>\n"
+ usage_msg = usage_msg + " Actions:\n"
+ usage_msg = usage_msg + " actionOutput <True|False> (default to True)\n"
+ usage_msg = usage_msg + " actionSetEthernetSrcAddr <source MAC address>\n"
+ usage_msg = usage_msg + " actionSetEthernetDstAddr <destination MAC address>\n"
+ usage_msg = usage_msg + " actionSetIPv4SrcAddr <source IPv4 address>\n"
+ usage_msg = usage_msg + " actionSetIPv4DstAddr <destination IPv4 address>\n"
+ usage_msg = usage_msg + " Actions (not implemented yet):\n"
+ usage_msg = usage_msg + " actionSetVlanId <VLAN ID>\n"
+ usage_msg = usage_msg + " actionSetVlanPriority <VLAN priority>\n"
+ usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
+ usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
+ usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
+ usage_msg = usage_msg + " actionStripVlan <True|False>\n"
+ usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
+
+ # app.debug = False;
+
+ # Usage info
+ if len(sys.argv) > 1 and (sys.argv[1] == "-h" or sys.argv[1] == "--help"):
+ print(usage_msg)
+ exit(0)
+
+ #
+ # Check the flags
+ #
+ start_argv_index = 1
+ if len(sys.argv) > 1 and sys.argv[1] == "-m":
+ MonitoringEnabled = True
+ start_argv_index = start_argv_index + 1
+
+ #
+ # Parse the remaining arguments
+ #
+ my_args = sys.argv[start_argv_index:]
+ parsed_args = copy.deepcopy(extract_flow_args(my_args))
+
+ last_data_path = []
+ my_flow_id = parsed_args['my_flow_id']
+ # Cleanup leftover state
+ delete_flow_path(my_flow_id)
+
+ while True:
+ data_path = compute_data_path(parsed_args)
+ if data_path != last_data_path:
+ if len(last_data_path) > 0:
+ delete_flow_path(my_flow_id)
+ flow_path = compute_flow_path(parsed_args, data_path)
+ add_flow_path(flow_path)
+ last_data_path = data_path
+
+ if MonitoringEnabled != True:
+ break
+ time.sleep(1)
diff --git a/web/delete_flow.py b/web/delete_flow.py
index f6f3d39..412d02f 100755
--- a/web/delete_flow.py
+++ b/web/delete_flow.py
@@ -59,4 +59,5 @@
exit(1)
# Do the work
- delete_flow_path(sys.argv[1]);
+ flow_id_arg = int(sys.argv[1], 0)
+ delete_flow_path(flow_id_arg);
diff --git a/web/get_flow.py b/web/get_flow.py
index dd6a8b6..fdaa10b 100755
--- a/web/get_flow.py
+++ b/web/get_flow.py
@@ -44,104 +44,114 @@
print "FlowPath: (flowId = %s installerId = %s src = %s/%s dst = %s/%s)" % (flowId, installerId, srcSwitch, srcPort, dstSwitch, dstPort)
for f in parsedResult['dataPath']['flowEntries']:
- inPort = f['inPort']['value']
- outPort = f['outPort']['value']
dpid = f['dpid']['value']
userState = f['flowEntryUserState']
switchState = f['flowEntrySwitchState']
match = f['flowEntryMatch'];
actions = f['flowEntryActions']
- print " FlowEntry: (%s, %s, %s, %s, %s)" % (inPort, dpid, outPort, userState, switchState)
+ print " FlowEntry: (%s, %s, %s)" % (dpid, userState, switchState)
- inPort = match['inPort']
- matchInPort = match['matchInPort']
- srcMac = match['srcMac']
- matchSrcMac = match['matchSrcMac']
- dstMac = match['dstMac']
- matchDstMac = match['matchDstMac']
- vlanId = match['vlanId']
- matchVlanId = match['matchVlanId']
- vlanPriority = match['vlanPriority']
- matchVlanPriority = match['matchVlanPriority']
- ethernetFrameType = match['ethernetFrameType']
- matchEthernetFrameType = match['matchEthernetFrameType']
- ipToS = match['ipToS']
- matchIpToS = match['matchIpToS']
- ipProto = match['ipProto']
- matchIpProto = match['matchIpProto']
- srcIPv4Net = match['srcIPv4Net']
- matchSrcIPv4Net = match['matchSrcIPv4Net']
- dstIPv4Net = match['dstIPv4Net']
- matchDstIPv4Net = match['matchDstIPv4Net']
- srcTcpUdpPort = match['srcTcpUdpPort']
- matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
- dstTcpUdpPort = match['dstTcpUdpPort']
- matchDstTcpUdpPort = match['matchDstTcpUdpPort']
- if matchInPort == True:
- print " inPort: %s" % inPort['value']
- if matchSrcMac == True:
- print " srcMac: %s" % srcMac['value']
- if matchDstMac == True:
- print " dstMac: %s" % dstMac['value']
- if matchVlanId == True:
- print " vlanId: %s" % vlanId
- if matchVlanPriority == True:
- print " vlanPriority: %s" % vlanPriority
- if matchEthernetFrameType == True:
- print " ethernetFrameType: %s" % ethernetFrameType
- if matchIpToS == True:
- print " ipToS: %s" % ipToS
- if matchIpProto == True:
- print " ipProto: %s" % ipProto
- if matchSrcIPv4Net == True:
- print " srcIPv4Net: %s" % srcIPv4Net['value']
- if matchDstIPv4Net == True:
- print " dstIPv4Net: %s" % dstIPv4Net['value']
- if matchSrcTcpUdpPort == True:
- print " srcTcpUdpPort: %s" % srcTcpUdpPort
- if matchDstTcpUdpPort == True:
- print " dstTcpUdpPort: %s" % dstTcpUdpPort
+ #
+ # Print the match conditions
+ #
+ if match == None:
+ print " Match: %s" % (match)
+ else:
+ inPort = match['inPort']
+ matchInPort = match['matchInPort']
+ srcMac = match['srcMac']
+ matchSrcMac = match['matchSrcMac']
+ dstMac = match['dstMac']
+ matchDstMac = match['matchDstMac']
+ vlanId = match['vlanId']
+ matchVlanId = match['matchVlanId']
+ vlanPriority = match['vlanPriority']
+ matchVlanPriority = match['matchVlanPriority']
+ ethernetFrameType = match['ethernetFrameType']
+ matchEthernetFrameType = match['matchEthernetFrameType']
+ ipToS = match['ipToS']
+ matchIpToS = match['matchIpToS']
+ ipProto = match['ipProto']
+ matchIpProto = match['matchIpProto']
+ srcIPv4Net = match['srcIPv4Net']
+ matchSrcIPv4Net = match['matchSrcIPv4Net']
+ dstIPv4Net = match['dstIPv4Net']
+ matchDstIPv4Net = match['matchDstIPv4Net']
+ srcTcpUdpPort = match['srcTcpUdpPort']
+ matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
+ dstTcpUdpPort = match['dstTcpUdpPort']
+ matchDstTcpUdpPort = match['matchDstTcpUdpPort']
+ if matchInPort == True:
+ print " inPort: %s" % inPort['value']
+ if matchSrcMac == True:
+ print " srcMac: %s" % srcMac['value']
+ if matchDstMac == True:
+ print " dstMac: %s" % dstMac['value']
+ if matchVlanId == True:
+ print " vlanId: %s" % vlanId
+ if matchVlanPriority == True:
+ print " vlanPriority: %s" % vlanPriority
+ if matchEthernetFrameType == True:
+ print " ethernetFrameType: %s" % hex(ethernetFrameType)
+ if matchIpToS == True:
+ print " ipToS: %s" % ipToS
+ if matchIpProto == True:
+ print " ipProto: %s" % ipProto
+ if matchSrcIPv4Net == True:
+ print " srcIPv4Net: %s" % srcIPv4Net['value']
+ if matchDstIPv4Net == True:
+ print " dstIPv4Net: %s" % dstIPv4Net['value']
+ if matchSrcTcpUdpPort == True:
+ print " srcTcpUdpPort: %s" % srcTcpUdpPort
+ if matchDstTcpUdpPort == True:
+ print " dstTcpUdpPort: %s" % dstTcpUdpPort
- for a in actions:
- actionType = a['actionType']
- if actionType == "ACTION_OUTPUT":
- port = a['actionOutput']['port']
- maxLen = a['actionOutput']['maxLen']
- print " actionType: %s port: %s maxLen: %s" % (actionType, port, maxLen)
- if actionType == "ACTION_SET_VLAN_VID":
- vlanId = a['actionSetVlanId']['vlanId']
- print " actionType: %s vlanId: %s" % (actionType, vlanId)
- if actionType == "ACTION_SET_VLAN_PCP":
- vlanPriority = a['actionSetVlanPriority']['vlanPriority']
- print " actionType: %s vlanPriority: %s" % (actionType, vlanPriority)
- if actionType == "ACTION_STRIP_VLAN":
- stripVlan = a['actionStripVlan']['stripVlan']
- print " actionType: %s stripVlan: %s" % (actionType, stripVlan)
- if actionType == "ACTION_SET_DL_SRC":
- setEthernetSrcAddr = a['actionSetEthernetSrcAddr']['addr']['value']
- print " actionType: %s setEthernetSrcAddr: %s" % (actionType, setEthernetSrcAddr)
- if actionType == "ACTION_SET_DL_DST":
- setEthernetDstAddr = a['actionSetEthernetDstAddr']['addr']['value']
- print " actionType: %s setEthernetDstAddr: %s" % (actionType, setEthernetDstAddr)
- if actionType == "ACTION_SET_NW_SRC":
- setIPv4SrcAddr = a['actionSetIPv4SrcAddr']['addr']['value']
- print " actionType: %s setIPv4SrcAddr: %s" % (actionType, setIPv4SrcAddr)
- if actionType == "ACTION_SET_NW_DST":
- setIPv4DstAddr = a['actionSetIPv4DstAddr']['addr']['value']
- print " actionType: %s setIPv4DstAddr: %s" % (actionType, setIPv4DstAddr)
- if actionType == "ACTION_SET_NW_TOS":
- setIpToS = a['actionSetIpToS']['ipToS']
- print " actionType: %s setIpToS: %s" % (actionType, setIpToS)
- if actionType == "ACTION_SET_TP_SRC":
- setTcpUdpSrcPort = a['actionSetTcpUdpSrcPort']['port']
- print " actionType: %s setTcpUdpSrcPort: %s" % (actionType, setTcpUdpSrcPort)
- if actionType == "ACTION_SET_TP_DST":
- setTcpUdpDstPort = a['actionSetTcpUdpDstPort']['port']
- print " actionType: %s setTcpUdpDstPort: %s" % (actionType, setTcpUdpDstPort)
- if actionType == "ACTION_ENQUEUE":
- port = a['actionEnqueue']['port']['value']
- queueId = a['actionEnqueue']['queueId']
- print " actionType: %s port: %s queueId: %s" % (actionType, port, queueId)
+ #
+ # Print the actions
+ #
+ if actions == None:
+ print " Actions: %s" % (actions)
+ else:
+ for a in actions:
+ actionType = a['actionType']
+ if actionType == "ACTION_OUTPUT":
+ port = a['actionOutput']['port']['value']
+ maxLen = a['actionOutput']['maxLen']
+ print " actionType: %s port: %s maxLen: %s" % (actionType, port, maxLen)
+ if actionType == "ACTION_SET_VLAN_VID":
+ vlanId = a['actionSetVlanId']['vlanId']
+ print " actionType: %s vlanId: %s" % (actionType, vlanId)
+ if actionType == "ACTION_SET_VLAN_PCP":
+ vlanPriority = a['actionSetVlanPriority']['vlanPriority']
+ print " actionType: %s vlanPriority: %s" % (actionType, vlanPriority)
+ if actionType == "ACTION_STRIP_VLAN":
+ stripVlan = a['actionStripVlan']['stripVlan']
+ print " actionType: %s stripVlan: %s" % (actionType, stripVlan)
+ if actionType == "ACTION_SET_DL_SRC":
+ setEthernetSrcAddr = a['actionSetEthernetSrcAddr']['addr']['value']
+ print " actionType: %s setEthernetSrcAddr: %s" % (actionType, setEthernetSrcAddr)
+ if actionType == "ACTION_SET_DL_DST":
+ setEthernetDstAddr = a['actionSetEthernetDstAddr']['addr']['value']
+ print " actionType: %s setEthernetDstAddr: %s" % (actionType, setEthernetDstAddr)
+ if actionType == "ACTION_SET_NW_SRC":
+ setIPv4SrcAddr = a['actionSetIPv4SrcAddr']['addr']['value']
+ print " actionType: %s setIPv4SrcAddr: %s" % (actionType, setIPv4SrcAddr)
+ if actionType == "ACTION_SET_NW_DST":
+ setIPv4DstAddr = a['actionSetIPv4DstAddr']['addr']['value']
+ print " actionType: %s setIPv4DstAddr: %s" % (actionType, setIPv4DstAddr)
+ if actionType == "ACTION_SET_NW_TOS":
+ setIpToS = a['actionSetIpToS']['ipToS']
+ print " actionType: %s setIpToS: %s" % (actionType, setIpToS)
+ if actionType == "ACTION_SET_TP_SRC":
+ setTcpUdpSrcPort = a['actionSetTcpUdpSrcPort']['port']
+ print " actionType: %s setTcpUdpSrcPort: %s" % (actionType, setTcpUdpSrcPort)
+ if actionType == "ACTION_SET_TP_DST":
+ setTcpUdpDstPort = a['actionSetTcpUdpDstPort']['port']
+ print " actionType: %s setTcpUdpDstPort: %s" % (actionType, setTcpUdpDstPort)
+ if actionType == "ACTION_ENQUEUE":
+ port = a['actionEnqueue']['port']['value']
+ queueId = a['actionEnqueue']['queueId']
+ print " actionType: %s port: %s queueId: %s" % (actionType, port, queueId)
def get_flow_path(flow_id):
try:
diff --git a/web/rest-test.sh b/web/rest-test.sh
new file mode 100755
index 0000000..a54e1e2
--- /dev/null
+++ b/web/rest-test.sh
@@ -0,0 +1,7 @@
+#! /bin/sh
+rm -f rest.json
+touch rest.json
+curl -s 'http://localhost:8080/wm/core/topology/switches/all/json' | python -m json.tool >> rest.json
+curl -s 'http://localhost:8080/wm/core/topology/links/json' | python -m json.tool >> rest.json
+curl -s 'http://localhost:8080/wm/registry/controllers/json' | python -m json.tool >> rest.json
+curl -s 'http://localhost:8080/wm/registry/switches/json' | python -m json.tool >> rest.json