Fixed removal of doubletagged hosts

Change-Id: I3e5fa5da4745f15ab6c84c899f80e7e622ce3583
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3Pipeline.java
index dbf1280..2ab8a18 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3Pipeline.java
@@ -38,6 +38,7 @@
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleOperations;
 import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.IndexTableId;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criteria;
@@ -47,6 +48,7 @@
 import org.onosproject.net.flow.criteria.TunnelIdCriterion;
 import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
@@ -243,6 +245,18 @@
     }
 
     /**
+     *
+     * @param meta The metadata instruction of this treatment
+     * @return True if we should remove both VLAN and Mac Termination flow entries.
+     *         This is only used for double tagged hosts.
+     */
+    public boolean shouldRemoveDoubleTagged(Instruction meta) {
+
+        Instructions.MetadataInstruction metadataInstruction = (Instructions.MetadataInstruction) meta;
+        return ((metadataInstruction.metadata() & metadataInstruction.metadataMask()) == 1);
+    }
+
+    /**
      * Configure filtering rules of outer and inner VLAN IDs, and a MAC address.
      * Filtering happens in three tables (VLAN_TABLE, VLAN_1_TABLE, TMAC_TABLE).
      *
@@ -258,6 +272,12 @@
         VlanIdCriterion innervidCriterion = null;
         VlanIdCriterion outerVidCriterion = null;
         boolean popVlan = false;
+        boolean removeDoubleTagged = true;
+        if (filteringObjective.meta().writeMetadata() != null) {
+            removeDoubleTagged = shouldRemoveDoubleTagged(filteringObjective.meta().writeMetadata());
+        }
+        log.info("HERE , removeDoubleTagged {}", removeDoubleTagged);
+
         TrafficTreatment meta = filteringObjective.meta();
         if (!filteringObjective.key().equals(Criteria.dummy()) &&
                 filteringObjective.key().type() == Criterion.Type.IN_PORT) {
@@ -337,7 +357,14 @@
                         if (matchInPortTmacTable()
                                 || (filteringObjective.meta() != null
                                 && filteringObjective.meta().clearedDeferred())) {
-                            ops = ops.remove(flowRule);
+
+                            // if metadata instruction not null and not removeDoubleTagged move on.
+                            if ((filteringObjective.meta().writeMetadata() != null) && (!removeDoubleTagged)) {
+                                log.info("Skipping removal of tmac rule for device {}", deviceId);
+                                continue;
+                            } else {
+                                ops = ops.remove(flowRule);
+                            }
                         } else {
                             log.debug("Abort TMAC flow removal on {}. Some other ports still share this TMAC flow");
                         }
@@ -352,6 +379,12 @@
         for (FlowRule flowRule : rules) {
             log.trace("{} flow rule in VLAN table: {} for dev: {}",
                       (install) ? "adding" : "removing", flowRule, deviceId);
+            // if context is remove, table is vlan_1 and removeDoubleTagged is false, continue.
+            if (flowRule.table().equals(IndexTableId.of(VLAN_TABLE)) &&
+                    !removeDoubleTagged && !install) {
+                log.info("Skipping removal of vlan table rule for now!");
+                continue;
+            }
             ops = install ? ops.add(flowRule) : ops.remove(flowRule);
         }