Refactor the interaction between the Flow Manager and the Flow Pusher.
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 ad5942c..dcd683d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -402,22 +402,49 @@
}
/**
+ * Inform the Flow Manager that a Flow Entry has 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.
+ */
+ 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);
+
+ //
+ // 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;
+ }
+ }
+
+ /**
* Push modified Flow-related state as appropriate.
*
* @param modifiedFlowPaths the collection of modified Flow Paths.
* @param modifiedFlowEntries the collection of modified Flow Entries.
*/
- public void pushModifiedFlowState(
- Collection<FlowPath> modifiedFlowPaths,
- Collection<FlowEntry> modifiedFlowEntries) {
+ void pushModifiedFlowState(Collection<FlowPath> modifiedFlowPaths,
+ Collection<FlowEntry> modifiedFlowEntries) {
//
// Push the modified Flow state:
// - Flow Entries to switches and the datagrid
// - Flow Paths to the database
//
pushModifiedFlowEntriesToSwitches(modifiedFlowEntries);
- pushModifiedFlowEntriesToDatagrid(modifiedFlowEntries);
pushModifiedFlowPathsToDatabase(modifiedFlowPaths);
+ cleanupDeletedFlowEntriesFromDatagrid(modifiedFlowEntries);
}
/**
@@ -453,21 +480,22 @@
log.error(logMsg);
continue;
}
-
- //
- // NOTE: Here we assume that the switch has been
- // successfully updated.
- //
- flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_UPDATED);
}
}
/**
- * Push modified Flow Entries to the datagrid.
+ * Cleanup deleted Flow Entries from the datagrid.
+ *
+ * NOTE: We cleanup only the Flow Entries that are not for our switches.
+ * This is needed to handle the case a switch going down:
+ * It has no Master controller instance, hence no controller instance
+ * will cleanup its flow entries.
+ * This is sub-optimal: we need to elect a controller instance to handle
+ * the cleanup of such orphaned flow entries.
*
* @param modifiedFlowEntries the collection of modified Flow Entries.
*/
- private void pushModifiedFlowEntriesToDatagrid(
+ private void cleanupDeletedFlowEntriesFromDatagrid(
Collection<FlowEntry> modifiedFlowEntries) {
if (modifiedFlowEntries.isEmpty())
return;
@@ -475,48 +503,31 @@
Map<Long, IOFSwitch> mySwitches = getMySwitches();
for (FlowEntry flowEntry : modifiedFlowEntries) {
+ //
+ // Process only Flow Entries that should be deleted and have
+ // a valid Flow Entry ID.
+ //
if (! flowEntry.isValidFlowEntryId())
continue;
-
- IOFSwitch mySwitch = mySwitches.get(flowEntry.dpid().value());
-
- //
- // TODO: For now Flow Entries are removed by all instances,
- // even if this Flow Entry is not for our switches.
- //
- // This is needed to handle the case a switch going down:
- // it has no Master controller instance, hence no
- // controller instance will cleanup its flow entries.
- // This is sub-optimal: we need to elect a controller
- // instance to handle the cleanup of such orphaned flow
- // entries.
- //
- if (mySwitch == null) {
- if (flowEntry.flowEntryUserState() !=
- FlowEntryUserState.FE_USER_DELETE) {
- continue;
- }
+ if (flowEntry.flowEntryUserState() !=
+ FlowEntryUserState.FE_USER_DELETE) {
+ continue;
}
- log.debug("Pushing Flow Entry To Datagrid: {}", flowEntry.toString());
+ //
+ // NOTE: The deletion of Flow Entries for my switches is handled
+ // elsewhere.
+ //
+ IOFSwitch mySwitch = mySwitches.get(flowEntry.dpid().value());
+ if (mySwitch != null)
+ continue;
+
+ log.debug("Pushing cleanup of Flow Entry To Datagrid: {}", flowEntry.toString());
+
//
// Write the Flow Entry to the Datagrid
//
- switch (flowEntry.flowEntryUserState()) {
- case FE_USER_ADD:
- if (mySwitch == null)
- break; // Install only flow entries for my switches
- datagridService.notificationSendFlowEntryAdded(flowEntry);
- break;
- case FE_USER_MODIFY:
- if (mySwitch == null)
- break; // Install only flow entries for my switches
- datagridService.notificationSendFlowEntryUpdated(flowEntry);
- break;
- case FE_USER_DELETE:
- datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
- break;
- }
+ datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
}
}
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 8d2b797..6d6043e 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
@@ -7,6 +7,7 @@
import net.onrc.onos.ofcontroller.topology.Topology;
import net.onrc.onos.ofcontroller.util.CallerId;
import net.onrc.onos.ofcontroller.util.DataPathEndpoints;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryId;
import net.onrc.onos.ofcontroller.util.FlowId;
import net.onrc.onos.ofcontroller.util.FlowPath;
@@ -106,7 +107,7 @@
* @return the network topology.
*/
Topology getTopology();
-
+
/**
* Get a globally unique flow ID from the flow service.
* NOTE: Not currently guaranteed to be globally unique.
@@ -122,4 +123,12 @@
* @param flowEntryId the Flow Entry ID of the expired Flow Entry.
*/
public void flowEntryOnSwitchExpired(IOFSwitch sw, FlowEntryId flowEntryId);
+
+ /**
+ * Inform the Flow Manager that a Flow Entry has 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.
+ */
+ void flowEntryPushedToSwitch(IOFSwitch sw, FlowEntry flowEntry);
}
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 438f478..792511c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
@@ -27,6 +27,7 @@
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.util.MACAddress;
import net.floodlightcontroller.util.OFMessageDamper;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
import net.onrc.onos.ofcontroller.util.FlowEntryAction;
import net.onrc.onos.ofcontroller.util.FlowEntryAction.*;
import net.onrc.onos.ofcontroller.util.FlowEntry;
@@ -51,6 +52,7 @@
*/
public class FlowPusher implements IFlowPusherService, IOFMessageListener {
private final static Logger log = LoggerFactory.getLogger(FlowPusher.class);
+ protected volatile IFlowService flowManager;
// NOTE: Below are moved from FlowManager.
// TODO: Values copied from elsewhere (class LearningSwitch).
@@ -267,6 +269,7 @@
this.threadPool = modContext.getServiceImpl(IThreadPoolService.class);
IFloodlightProviderService flservice = modContext.getServiceImpl(IFloodlightProviderService.class);
flservice.addOFMessageListener(OFType.BARRIER_REPLY, this);
+ flowManager = modContext.getServiceImpl(IFlowService.class);
if (damper != null) {
messageDamper = damper;
@@ -709,17 +712,19 @@
+ 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.
//
- // TODO: The FlowEntry Object in Titan should be set
- // to FE_SWITCH_UPDATED.
- //
-
- return add(sw,fm);
+ flowManager.flowEntryPushedToSwitch(sw, flowEntry);
+
+ return true;
}
@Override