Added delete all flow rules during Corsa switch handshake

Change-Id: I885dad9453754bf86f12d4a86541fe7bfe7efd72

added delete all rules in corsa switch handshake

Change-Id: I7905a754653f6fc7eb8643023372e6dfa779cf26
diff --git a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
index 413401a..1035cd6 100644
--- a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
+++ b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
@@ -298,6 +298,7 @@
                     .setEthDst(nextHop.mac())
                     .pushVlan()
                     .setVlanId(egressIntf.vlan())
+                    .setVlanPcp((byte) 0)
                     .setOutput(egressIntf.connectPoint().port())
                     .build();
 
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java
index 2c62c74..6b32bcd 100644
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java
+++ b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java
@@ -16,25 +16,31 @@
 package org.onosproject.openflow.drivers;
 
 import com.google.common.collect.Lists;
-
 import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
+import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFFlowMod;
 import org.projectfloodlight.openflow.protocol.OFMessage;
 import org.projectfloodlight.openflow.protocol.OFType;
 import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
+import org.projectfloodlight.openflow.types.OFGroup;
 import org.projectfloodlight.openflow.types.TableId;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Corsa switch driver for BGP Router deployment.
  */
 public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
+
     private static final int FIRST_TABLE = 0;
     private static final int VLAN_MPLS_TABLE = 1;
     private static final int VLAN_TABLE = 2;
@@ -44,6 +50,10 @@
     private static final int FIB_TABLE = 6;
     private static final int LOCAL_TABLE = 9;
 
+    private AtomicBoolean handShakeComplete = new AtomicBoolean(false);
+
+    private int barrierXid;
+
     OFCorsaSwitchDriver(Dpid dpid, OFDescStatsReply desc) {
         super(dpid);
 
@@ -222,13 +232,46 @@
     }
 
     @Override
-    public void startDriverHandshake() {}
+    public void startDriverHandshake() {
+        if (startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeAlreadyStarted();
+        }
+        startDriverHandshakeCalled = true;
+        OFFlowMod fm = factory().buildFlowDelete()
+                .setTableId(TableId.ALL)
+                .setOutGroup(OFGroup.ANY)
+                .build();
 
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        return true;
+        channel.write(Collections.singletonList(fm));
+
+        barrierXid = getNextTransactionId();
+        OFBarrierRequest barrier = factory().buildBarrierRequest()
+                .setXid(barrierXid).build();
+
+
+        channel.write(Collections.singletonList(barrier));
+
     }
 
     @Override
-    public void processDriverHandshakeMessage(OFMessage m) {}
+    public boolean isDriverHandshakeComplete() {
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeAlreadyStarted();
+        }
+        return handShakeComplete.get();
+    }
+
+    @Override
+    public void processDriverHandshakeMessage(OFMessage m) {
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeNotStarted();
+        }
+        if (handShakeComplete.get()) {
+            throw new SwitchDriverSubHandshakeCompleted(m);
+        }
+        if (m.getType() == OFType.BARRIER_REPLY &&
+                m.getXid() == barrierXid) {
+            handShakeComplete.set(true);
+        }
+    }
 }
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
index ede50f4..17bfc11 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
@@ -95,17 +95,6 @@
     private final FlowType type;
     private Type tableType = FlowRule.Type.DEFAULT;
 
-
-    public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) {
-        this.stat = entry;
-        this.match = entry.getMatch();
-        this.instructions = getInstructions(entry);
-        this.dpid = dpid;
-        this.removed = null;
-        this.flowMod = null;
-        this.type = FlowType.STAT;
-    }
-
     public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry, Type tableType) {
         this.stat = entry;
         this.match = entry.getMatch();
@@ -117,7 +106,7 @@
         this.tableType = tableType;
     }
 
-    public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) {
+    public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed, Type tableType) {
         this.match = removed.getMatch();
         this.removed = removed;
 
@@ -126,10 +115,11 @@
         this.stat = null;
         this.flowMod = null;
         this.type = FlowType.REMOVED;
+        this.tableType = tableType;
 
     }
 
-    public FlowEntryBuilder(Dpid dpid, OFFlowMod fm) {
+    public FlowEntryBuilder(Dpid dpid, OFFlowMod fm, Type tableType) {
         this.match = fm.getMatch();
         this.dpid = dpid;
         this.instructions = getInstructions(fm);
@@ -137,6 +127,7 @@
         this.flowMod = fm;
         this.stat = null;
         this.removed = null;
+        this.tableType = tableType;
     }
 
     public FlowEntry build(FlowEntryState... state) {
@@ -153,14 +144,16 @@
             case REMOVED:
                 rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
                                       buildSelector(), null, removed.getPriority(),
-                                      removed.getCookie().getValue(), removed.getIdleTimeout(), false);
+                                      removed.getCookie().getValue(), removed.getIdleTimeout(), false,
+                                      tableType);
                 return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(),
                                       removed.getPacketCount().getValue(), removed.getByteCount().getValue());
             case MOD:
                 FlowEntryState flowState = state.length > 0 ? state[0] : FlowEntryState.FAILED;
                 rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
                                       buildSelector(), buildTreatment(), flowMod.getPriority(),
-                                      flowMod.getCookie().getValue(), flowMod.getIdleTimeout(), false);
+                                      flowMod.getCookie().getValue(), flowMod.getIdleTimeout(), false,
+                                      tableType);
                 return new DefaultFlowEntry(rule, flowState, 0, 0, 0);
             default:
                 log.error("Unknown flow type : {}", this.type);
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
index bf4c73f..1c4b20e 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
@@ -305,11 +305,13 @@
 
         @Override
         public void handleMessage(Dpid dpid, OFMessage msg) {
+            OpenFlowSwitch sw = controller.getSwitch(dpid);
             switch (msg.getType()) {
                 case FLOW_REMOVED:
                     OFFlowRemoved removed = (OFFlowRemoved) msg;
 
-                    FlowEntry fr = new FlowEntryBuilder(dpid, removed).build();
+                    FlowEntry fr = new FlowEntryBuilder(dpid, removed,
+                                                        getType(sw.getTableType(removed.getTableId()))).build();
                     providerService.flowRemoved(fr);
                     break;
                 case STATS_REPLY:
@@ -340,7 +342,9 @@
                             OFFlowMod fm = (OFFlowMod) m;
                             InternalCacheEntry entry = pendingBatches.getIfPresent(msg.getXid());
                             if (entry != null) {
-                                entry.appendFailure(new FlowEntryBuilder(dpid, fm).build());
+                                entry.appendFailure(new FlowEntryBuilder(dpid, fm,
+                                                                         getType(sw.getTableType(fm.getTableId())))
+                                                                         .build());
                             } else {
                                 log.error("No matching batch for this error: {}", error);
                             }