diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java index 490c50ecb7d6d971368bc50d319e075d679f7faf..27750c91962dbf3371275c316b22cccf7203e292 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java @@ -358,17 +358,23 @@ public class StaticFlowEntryPusher if (dpidOldFlowMod != null) { oldFlowMod = entriesFromStorage.get(dpidOldFlowMod).remove(entry); } - if (oldFlowMod != null) { - // Remove any pre-existing rule - // If the old rule is on a different switch - // then we have to handle that as well. - oldFlowMod.setCommand(OFFlowMod.OFPFC_DELETE_STRICT); - if (dpidOldFlowMod.equals(dpid)) { - outQueue.add(oldFlowMod); - } else { - writeOFMessageToSwitch(HexString.toLong(dpidOldFlowMod), oldFlowMod); + if (oldFlowMod != null && newFlowMod != null) { + // set the new flow mod to modify a pre-existing rule if these fields match + if(oldFlowMod.getMatch().equals(newFlowMod.getMatch()) + && oldFlowMod.getCookie() == newFlowMod.getCookie() + && oldFlowMod.getPriority() == newFlowMod.getPriority()){ + newFlowMod.setCommand(OFFlowMod.OFPFC_MODIFY_STRICT); + // if they don't match delete the old flow + } else{ + oldFlowMod.setCommand(OFFlowMod.OFPFC_DELETE_STRICT); + if (dpidOldFlowMod.equals(dpid)) { + outQueue.add(oldFlowMod); + } else { + writeOFMessageToSwitch(HexString.toLong(dpidOldFlowMod), oldFlowMod); + } } } + // write the new flow if (newFlowMod != null) { entriesFromStorage.get(dpid).put(entry, newFlowMod); outQueue.add(newFlowMod); @@ -378,7 +384,6 @@ public class StaticFlowEntryPusher entry2dpid.remove(entry); } } - writeOFMessagesToSwitch(HexString.toLong(dpid), outQueue); } } diff --git a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java index 186fd69699f1a4490fedd4f4a73569cd46b93fed..f01e8ae374eb40001a2a3c0a8bedf5e480e66dfc 100644 --- a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java +++ b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java @@ -18,6 +18,7 @@ import org.openflow.protocol.OFMessage; import org.openflow.protocol.OFPort; import org.openflow.protocol.action.OFAction; import org.openflow.protocol.action.OFActionOutput; +import org.openflow.protocol.action.OFActionStripVirtualLan; import org.openflow.util.HexString; @@ -259,7 +260,7 @@ public class StaticFlowTests extends FloodlightTestCase { contextCapture.reset(); writeCaptureList.reset(); - // now try an update, calling staticFlowPusher.rowUpdated() + // now try an overwriting update, calling staticFlowPusher.rowUpdated() TestRule3.put(COLUMN_DL_VLAN, 333); storage.updateRow(StaticFlowEntryPusher.TABLE_NAME, TestRule3); assertEquals(2, staticFlowEntryPusher.countEntries()); @@ -274,6 +275,23 @@ public class StaticFlowTests extends FloodlightTestCase { FlowMod3.getMatch().fromString("dl_dst=00:20:30:40:50:60,dl_vlan=333"); OFFlowMod updateFlowMod = (OFFlowMod) outList.get(1); verifyFlowMod(updateFlowMod, FlowMod3); + writeCaptureList.reset(); + + // now try an action modifying update, calling staticFlowPusher.rowUpdated() + TestRule3.put(COLUMN_ACTIONS, "output=controller,strip-vlan"); // added strip-vlan + storage.updateRow(StaticFlowEntryPusher.TABLE_NAME, TestRule3); + assertEquals(2, staticFlowEntryPusher.countEntries()); + assertEquals(1, writeCaptureList.getValues().size()); + + outList = (List<OFMessage>) writeCaptureList.getValues().get(0); + assertEquals(1, outList.size()); + OFFlowMod modifyFlowMod = (OFFlowMod) outList.get(0); + FlowMod3.setCommand(OFFlowMod.OFPFC_MODIFY_STRICT); + List<OFAction> modifiedActions = FlowMod3.getActions(); + modifiedActions.add(new OFActionStripVirtualLan()); // add the new action to what we should expect + FlowMod3.setActions(modifiedActions); + FlowMod3.setLengthU(OFFlowMod.MINIMUM_LENGTH + 16); // accommodate the addition of new actions + verifyFlowMod(modifyFlowMod, FlowMod3); }