Fix a bug when processing Flow Entry notifications and updating the
locally stored FlowEntries. Previously, even if a Flow Entry
wasn't updated, it could trigger multiple writing of a FlowPath
to the Database. Now we explicitly check whether the
locally stored FlowEntry is actually updated.
As a side-effect of the above fix now we have to:
(1) Create a copy of a FlowEntry inside FlowManager.flowEntriesPushedToSwitch()
before modifying it and pushing it into the Datagrid
(2) We have to explicitly check whether all Flow Entries have been installed
into the switches before writing a FlowPath to the Graph DB.
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 82680df..88a0cbf 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -405,32 +405,40 @@
//
// Process all entries
//
+ // TODO: For now we have to create an explicit FlowEntry copy so
+ // we don't modify the original FlowEntry.
+ // This should go away after we start using the OpenFlow Barrier
+ // mechnanism in the FlowPusher.
+ //
+ Kryo kryo = kryoFactory.newKryo();
for (Pair<IOFSwitch, FlowEntry> entry : entries) {
FlowEntry flowEntry = entry.second;
//
// Mark the Flow Entry that it has been pushed to the switch
//
- flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_UPDATED);
+ FlowEntry copyFlowEntry = kryo.copy(flowEntry);
+ copyFlowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_UPDATED);
//
// Write the Flow Entry to the Datagrid
//
- switch (flowEntry.flowEntryUserState()) {
+ switch (copyFlowEntry.flowEntryUserState()) {
case FE_USER_ADD:
- datagridService.notificationSendFlowEntryAdded(flowEntry);
+ datagridService.notificationSendFlowEntryAdded(copyFlowEntry);
break;
case FE_USER_MODIFY:
- datagridService.notificationSendFlowEntryUpdated(flowEntry);
+ datagridService.notificationSendFlowEntryUpdated(copyFlowEntry);
break;
case FE_USER_DELETE:
- datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
+ datagridService.notificationSendFlowEntryRemoved(copyFlowEntry.flowEntryId());
break;
case FE_USER_UNKNOWN:
assert(false);
break;
}
}
+ kryoFactory.deleteKryo(kryo);
}
/**
@@ -687,6 +695,11 @@
allValid = false;
break;
}
+ if (flowEntry.flowEntrySwitchState() !=
+ FlowEntrySwitchState.FE_SWITCH_UPDATED) {
+ allValid = false;
+ break;
+ }
}
if (! allValid)
continue;