Changed implementation of pushFlows to give better performance than pushFlow

Change-Id: I78a5e8b03c705852b99e5eda861dfaf9c7e5ba35
diff --git a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
index 8ac2912..6ad24ec 100644
--- a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
@@ -22,17 +22,22 @@
      * operation and match-action definition, and subject to the TTP supported
      * by a switch implementing this interface. It is up to the implementation
      * to translate the 'matchActionOp' into a match-instruction with actions,
-     * as expected by OF 1.3 switches.
-     * 
-     * @param matchActionOp
+     * as expected by OF 1.3 switches. For better performance, use
+     * {@link pushFlows}
+     *
+     * @param matchActionOp information required to create a flow-mod and push
+     *        it to the switch
      * @throws IOException
      */
     public void pushFlow(MatchActionOperationEntry matchActionOp) throws IOException;
 
     /**
-     * Pushes a collection of flows to the switch.
-     *
-     * @param matchActionOps
+     * Pushes a collection of flows to the switch, at the same time. Can result
+     * in better performance, when compared to sending flows one at a time using
+     * {@link pushFlow}, especially if the number of flows is large.
+     * 
+     * @param matchActionOps a collection of information required to create a
+     *        flowmod
      * @throws IOException
      */
     public void pushFlows(Collection<MatchActionOperationEntry> matchActionOps)
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
index 254e658..30b8059 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
@@ -372,7 +372,7 @@
         this.write(msglist);
     }
 
-    public void write(List<OFMessage> msglist) throws IOException {
+    protected void write(List<OFMessage> msglist) throws IOException {
         this.channel.write(msglist);
     }
 
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
index b28ddc0..5d4a9ec 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
@@ -723,8 +723,8 @@
                     .ethDst(b.dstMac);
             OFAction setDA = factory.actions().buildSetField()
                     .setField(dmac).build();
-            OFOxmEthDst smac = factory.oxms()
-                    .ethDst(b.srcMac);
+            OFOxmEthSrc smac = factory.oxms()
+                    .ethSrc(b.srcMac);
             OFAction setSA = factory.actions().buildSetField()
                     .setField(smac).build();
             OFAction outp = factory.actions().buildOutput()
@@ -838,7 +838,7 @@
         return ofAction;
     }
 
-    private void pushIpEntry(MatchActionOperationEntry mao) throws IOException {
+    private OFMessage getIpEntry(MatchActionOperationEntry mao) {
         MatchAction ma = mao.getTarget();
         Operator op = mao.getOperator();
         Ipv4Match ipm = (Ipv4Match) ma.getMatch();
@@ -905,14 +905,14 @@
                     .setXid(getNextTransactionId())
                     .build();
         }
-        write(ipFlow, null);
         log.debug("{} ip-rule {}-{} in sw {}",
                 (op == MatchActionOperations.Operator.ADD) ? "Adding" : "Deleting",
                 match, writeActions,
                 getStringId());
+        return ipFlow;
     }
 
-    private void pushMplsEntry(MatchActionOperationEntry mao) throws IOException {
+    private OFMessage getMplsEntry(MatchActionOperationEntry mao) {
         MatchAction ma = mao.getTarget();
         Operator op = mao.getOperator();
         MplsMatch mplsm = (MplsMatch) ma.getMatch();
@@ -968,15 +968,17 @@
                     .setXid(getNextTransactionId())
                     .build();
         }
-        write(mplsFlow, null);
         log.debug("{} mpls-rule {}-{} in sw {}",
                 (op == MatchActionOperations.Operator.ADD) ? "Adding" : "Deleting",
                 matchlabel, writeActions,
                 getStringId());
+        return mplsFlow;
     }
 
-    private void pushAclEntry(MatchActionOperationEntry mao) {
+    private OFMessage getAclEntry(MatchActionOperationEntry mao) {
 
+        OFMessage aclFlow = null;
+        return aclFlow;
     }
 
     // *****************************
@@ -985,26 +987,39 @@
 
     @Override
     public void pushFlow(MatchActionOperationEntry matchActionOp) throws IOException {
+        OFMessage ofm = getFlow(matchActionOp);
+        if (ofm != null) {
+            write(Collections.singletonList(ofm));
+        }
+    }
+
+    private OFMessage getFlow(MatchActionOperationEntry matchActionOp) {
         final MatchAction matchAction = matchActionOp.getTarget();
         final Match match = matchAction.getMatch();
         if (match instanceof Ipv4Match) {
-            pushIpEntry(matchActionOp);
+            return getIpEntry(matchActionOp);
         } else if (match instanceof MplsMatch) {
-            pushMplsEntry(matchActionOp);
+            return getMplsEntry(matchActionOp);
         } else if (match instanceof PacketMatch) {
-            pushAclEntry(matchActionOp);
+            return getAclEntry(matchActionOp);
         } else {
             log.error("Unknown match type {} pushed to switch {}", match,
                     getStringId());
         }
+        return null;
     }
 
     @Override
     public void pushFlows(Collection<MatchActionOperationEntry> matchActionOps)
             throws IOException {
+        List<OFMessage> flowMods = new ArrayList<OFMessage>();
         for (MatchActionOperationEntry matchActionOp : matchActionOps) {
-            pushFlow(matchActionOp);
+            OFMessage ofm = getFlow(matchActionOp);
+            if (ofm != null) {
+                flowMods.add(ofm);
+            }
         }
+        write(flowMods);
     }
 
     @Override