Merge branch 'ONOS' into syncdev17
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 dcd683d..9601ff9 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -4,6 +4,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
@@ -402,30 +403,41 @@
}
/**
- * Inform the Flow Manager that a Flow Entry has been pushed to a switch.
+ * Inform the Flow Manager that a collection of Flow Entries have been
+ * pushed to a switch.
*
- * @param sw the switch the Flow Entry has been pushed to.
- * @param flowEntry the Flow Entry that has been pushed.
+ * @param entries the collection of <IOFSwitch, FlowEntry> pairs
+ * that have been pushed.
*/
- public void flowEntryPushedToSwitch(IOFSwitch sw, FlowEntry flowEntry) {
- //
- // Mark the Flow Entry that it has been pushed to the switch
- //
- flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_UPDATED);
+ public void flowEntriesPushedToSwitch(
+ Collection<Pair<IOFSwitch, FlowEntry>> entries) {
//
- // Write the Flow Entry to the Datagrid
+ // Process all entries
//
- switch (flowEntry.flowEntryUserState()) {
- case FE_USER_ADD:
- datagridService.notificationSendFlowEntryAdded(flowEntry);
- break;
- case FE_USER_MODIFY:
- datagridService.notificationSendFlowEntryUpdated(flowEntry);
- break;
- case FE_USER_DELETE:
- datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
- break;
+ for (Pair<IOFSwitch, FlowEntry> entry : entries) {
+ IOFSwitch sw = entry.first;
+ FlowEntry flowEntry = entry.second;
+
+ //
+ // Mark the Flow Entry that it has been pushed to the switch
+ //
+ flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_UPDATED);
+
+ //
+ // Write the Flow Entry to the Datagrid
+ //
+ switch (flowEntry.flowEntryUserState()) {
+ case FE_USER_ADD:
+ datagridService.notificationSendFlowEntryAdded(flowEntry);
+ break;
+ case FE_USER_MODIFY:
+ datagridService.notificationSendFlowEntryUpdated(flowEntry);
+ break;
+ case FE_USER_DELETE:
+ datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
+ break;
+ }
}
}
@@ -460,27 +472,36 @@
if (modifiedFlowEntries.isEmpty())
return;
+ List<Pair<IOFSwitch, FlowEntry>> entries =
+ new LinkedList<Pair<IOFSwitch, FlowEntry>>();
+
Map<Long, IOFSwitch> mySwitches = getMySwitches();
+ //
+ // Create a collection of my Flow Entries to push
+ //
for (FlowEntry flowEntry : modifiedFlowEntries) {
IOFSwitch mySwitch = mySwitches.get(flowEntry.dpid().value());
if (mySwitch == null)
continue;
- log.debug("Pushing Flow Entry To Switch: {}", flowEntry.toString());
-
//
- // Push the Flow Entry into the switch
+ // Assign Flow Entry IDs if missing.
//
- if (! pusher.add(mySwitch, flowEntry)) {
- String logMsg = "Cannot install Flow Entry " +
- flowEntry.flowEntryId() +
- " from Flow Path " + flowEntry.flowId() +
- " on switch " + flowEntry.dpid();
- log.error(logMsg);
- continue;
+ // NOTE: This is an additional safeguard, in case the
+ // mySwitches set has changed (after the Flow Entry IDs
+ // assignments by the caller).
+ //
+ if (! flowEntry.isValidFlowEntryId()) {
+ long id = getNextFlowEntryId();
+ flowEntry.setFlowEntryId(new FlowEntryId(id));
}
+
+ log.debug("Pushing Flow Entry To Switch: {}", flowEntry.toString());
+ entries.add(new Pair<IOFSwitch, FlowEntry>(mySwitch, flowEntry));
}
+
+ pusher.pushFlowEntries(entries);
}
/**
@@ -611,6 +632,16 @@
for (FlowPath flowPath : modifiedFlowPaths) {
//
+ // Don't push Flow Paths that are deleted by the user.
+ // Those will be deleted at the ONOS instance that received the
+ // API call to delete the flow.
+ //
+ if (flowPath.flowPathUserState() ==
+ FlowPathUserState.FP_USER_DELETE) {
+ continue;
+ }
+
+ //
// Push the changes only on the instance responsible for the
// first switch.
//
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
index 6d6043e..3a8a947 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
@@ -1,6 +1,7 @@
package net.onrc.onos.ofcontroller.flowmanager;
import java.util.ArrayList;
+import java.util.Collection;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.IFloodlightService;
@@ -11,6 +12,7 @@
import net.onrc.onos.ofcontroller.util.FlowEntryId;
import net.onrc.onos.ofcontroller.util.FlowId;
import net.onrc.onos.ofcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.util.Pair;
/**
* Interface for providing Flow Service to other modules.
@@ -125,10 +127,12 @@
public void flowEntryOnSwitchExpired(IOFSwitch sw, FlowEntryId flowEntryId);
/**
- * Inform the Flow Manager that a Flow Entry has been pushed to a switch.
+ * Inform the Flow Manager that a collection of Flow Entries have been
+ * pushed to a switch.
*
- * @param sw the switch the Flow Entry has been pushed to.
- * @param flowEntry the Flow Entry that has been pushed.
+ * @param entries the collection of <IOFSwitch, FlowEntry> pairs
+ * that have been pushed.
*/
- void flowEntryPushedToSwitch(IOFSwitch sw, FlowEntry flowEntry);
+ public void flowEntriesPushedToSwitch(
+ Collection<Pair<IOFSwitch, FlowEntry>> entries);
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
index 792511c..c3c7107 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
@@ -3,9 +3,11 @@
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -36,6 +38,7 @@
import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
import net.onrc.onos.ofcontroller.util.FlowEntryUserState;
import net.onrc.onos.ofcontroller.util.IPv4Net;
+import net.onrc.onos.ofcontroller.util.Pair;
import net.onrc.onos.ofcontroller.util.Port;
/**
@@ -446,9 +449,46 @@
return true;
}
-
+
@Override
- public boolean add(IOFSwitch sw, FlowEntry flowEntry) {
+ public void pushFlowEntries(
+ Collection<Pair<IOFSwitch, FlowEntry>> entries) {
+
+ List<Pair<IOFSwitch, FlowEntry>> pushedEntries =
+ new LinkedList<Pair<IOFSwitch, FlowEntry>>();
+
+ for (Pair<IOFSwitch, FlowEntry> entry : entries) {
+ if (add(entry.first, entry.second)) {
+ pushedEntries.add(entry);
+ }
+ }
+
+ //
+ // TODO: We should use the OpenFlow Barrier mechanism
+ // to check for errors, and update the SwitchState
+ // for a flow entry after the Barrier message is
+ // is received.
+ // Only after inform the Flow Manager that the entry is pushed.
+ //
+ flowManager.flowEntriesPushedToSwitch(pushedEntries);
+ }
+
+ @Override
+ public void pushFlowEntry(IOFSwitch sw, FlowEntry flowEntry) {
+ Collection<Pair<IOFSwitch, FlowEntry>> entries =
+ new LinkedList<Pair<IOFSwitch, FlowEntry>>();
+
+ entries.add(new Pair<IOFSwitch, FlowEntry>(sw, flowEntry));
+ pushFlowEntries(entries);
+ }
+
+ /**
+ * Create a message from FlowEntry and add it to the queue of the switch.
+ * @param sw Switch to which message is pushed.
+ * @param flowEntry FlowEntry object used for creating message.
+ * @return true if message is successfully added to a queue.
+ */
+ private boolean add(IOFSwitch sw, FlowEntry flowEntry) {
//
// Create the OpenFlow Flow Modification Entry to push
//
@@ -712,19 +752,7 @@
+ matchSrcMac + " dstMac: " + matchDstMac + " inPort: "
+ matchInPort + " outPort: " + actionOutputPort);
- if (add(sw, fm) != true)
- return false;
-
- //
- // TODO: We should use the OpenFlow Barrier mechanism
- // to check for errors, and update the SwitchState
- // for a flow entry after the Barrier message is
- // is received.
- // Only after inform the Flow Manager that the entry is pushed.
- //
- flowManager.flowEntryPushedToSwitch(sw, flowEntry);
-
- return true;
+ return add(sw, fm);
}
@Override
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
index c357e7c..7d5527b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
@@ -246,7 +246,7 @@
return;
}
- pusher.add(sw, flowEntry);
+ pusher.pushFlowEntry(sw, flowEntry);
}
/**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowPusherService.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowPusherService.java
index 2f550a7..6bf20d9 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowPusherService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowPusherService.java
@@ -1,5 +1,7 @@
package net.onrc.onos.ofcontroller.flowprogrammer;
+import java.util.Collection;
+
import org.openflow.protocol.OFBarrierReply;
import org.openflow.protocol.OFMessage;
@@ -7,6 +9,7 @@
import net.floodlightcontroller.core.internal.OFMessageFuture;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.Pair;
/**
* FlowPusherService is a service to send message to switches in proper rate.
@@ -47,6 +50,9 @@
/**
* Add a message to the queue of the switch.
+ *
+ * Note: Notification is NOT delivered for the pushed message.
+ *
* @param sw Switch to which message is pushed.
* @param msg Message object to be added.
* @return true if message is successfully added to a queue.
@@ -54,12 +60,28 @@
boolean add(IOFSwitch sw, OFMessage msg);
/**
- * Create a message from FlowEntry and add it to the queue of the switch.
+ * Push a collection of Flow Entries to the corresponding switches.
+ *
+ * Note: Notification is delivered for the Flow Entries that
+ * are pushed successfully.
+ *
+ * @param entries the collection of <IOFSwitch, FlowEntry> pairs
+ * to push.
+ */
+ void pushFlowEntries(Collection<Pair<IOFSwitch, FlowEntry>> entries);
+
+ /**
+ * Create a message from FlowEntry and add it to the queue of the
+ * switch.
+ *
+ * Note: Notification is delivered for the Flow Entries that
+ * are pushed successfully.
+ *
* @param sw Switch to which message is pushed.
* @param flowEntry FlowEntry object used for creating message.
* @return true if message is successfully added to a queue.
*/
- boolean add(IOFSwitch sw, FlowEntry flowEntry);
+ void pushFlowEntry(IOFSwitch sw, FlowEntry flowEntry);
/**
* Set sending rate to a switch.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/Pair.java b/src/main/java/net/onrc/onos/ofcontroller/util/Pair.java
new file mode 100644
index 0000000..2245758
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/Pair.java
@@ -0,0 +1,20 @@
+package net.onrc.onos.ofcontroller.util;
+
+/**
+ * A generic class representing a pair of two values.
+ */
+public class Pair<F, S> {
+ public F first; // The first value in the pair
+ public S second; // The second value in the pair
+
+ /**
+ * Constructor for a pair of two values.
+ *
+ * @param first the first value in the pair.
+ * @param second the second value in the pair.
+ */
+ public Pair(F first, S second) {
+ this.first = first;
+ this.second = second;
+ }
+}