adding a criterion for inner vlans
used by olt to match on the inner vlan

Change-Id: I7671b68d9860d598395cba134a589ca23f264c7e
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/CriterionCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
index 975503b..1d7c47e 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
@@ -38,6 +38,8 @@
     protected static final String METADATA = "metadata";
 
     protected static final String VLAN_ID = "vlanId";
+    protected static final String INNER_VLAN_ID = "innerVlanId";
+    protected static final String INNER_PRIORITY = "innerPriority";
     protected static final String PRIORITY = "priority";
     protected static final String IP_DSCP = "ipDscp";
     protected static final String IP_ECN = "ipEcn";
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/DecodeCriterionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/DecodeCriterionCodecHelper.java
index 88cc332..cd28afc 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/DecodeCriterionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/DecodeCriterionCodecHelper.java
@@ -72,6 +72,8 @@
         decoderMap.put(Criterion.Type.ETH_TYPE.name(), new EthTypeDecoder());
         decoderMap.put(Criterion.Type.VLAN_VID.name(), new VlanVidDecoder());
         decoderMap.put(Criterion.Type.VLAN_PCP.name(), new VlanPcpDecoder());
+        decoderMap.put(Criterion.Type.INNER_VLAN_VID.name(), new InnerVlanVidDecoder());
+        decoderMap.put(Criterion.Type.INNER_VLAN_PCP.name(), new InnerVlanPcpDecoder());
         decoderMap.put(Criterion.Type.IP_DSCP.name(), new IpDscpDecoder());
         decoderMap.put(Criterion.Type.IP_ECN.name(), new IpEcnDecoder());
         decoderMap.put(Criterion.Type.IP_PROTO.name(), new IpProtoDecoder());
@@ -139,7 +141,8 @@
         @Override
         public Criterion decodeCriterion(ObjectNode json) {
             PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
-                    CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
+                                                                  CriterionCodec.PORT +
+                                                                          MISSING_MEMBER_MESSAGE).asLong());
 
             return Criteria.matchInPort(port);
         }
@@ -149,7 +152,8 @@
         @Override
         public Criterion decodeCriterion(ObjectNode json) {
             PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
-                    CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
+                                                                  CriterionCodec.PORT +
+                                                                          MISSING_MEMBER_MESSAGE).asLong());
 
             return Criteria.matchInPhyPort(port);
         }
@@ -179,12 +183,34 @@
         @Override
         public Criterion decodeCriterion(ObjectNode json) {
             byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY),
-                    CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
+                    CriterionCodec.PRIORITY + MISSING_MEMBER_MESSAGE).asInt();
 
             return Criteria.matchVlanPcp(priority);
         }
     }
 
+    private class InnerVlanVidDecoder implements CriterionDecoder {
+        @Override
+        public Criterion decodeCriterion(ObjectNode json) {
+            short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.INNER_VLAN_ID),
+                                                 CriterionCodec.INNER_VLAN_ID +
+                                                         MISSING_MEMBER_MESSAGE).asInt();
+
+            return Criteria.matchInnerVlanId(VlanId.vlanId(vlanId));
+        }
+    }
+
+    private class InnerVlanPcpDecoder implements CriterionDecoder {
+        @Override
+        public Criterion decodeCriterion(ObjectNode json) {
+            byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.INNER_PRIORITY),
+                                                 CriterionCodec.INNER_PRIORITY +
+                                                         MISSING_MEMBER_MESSAGE).asInt();
+
+            return Criteria.matchInnerVlanPcp(priority);
+        }
+    }
+
     private class IpDscpDecoder implements CriterionDecoder {
         @Override
         public Criterion decodeCriterion(ObjectNode json) {
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
index 1852ee2..2130293 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
@@ -84,6 +84,8 @@
         formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
         formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
         formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
+        formatMap.put(Criterion.Type.INNER_VLAN_VID, new FormatInnerVlanVid());
+        formatMap.put(Criterion.Type.INNER_VLAN_PCP, new FormatInnerVlanPcp());
         formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
         formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
         formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
@@ -194,6 +196,24 @@
         }
     }
 
+    private static class FormatInnerVlanVid implements CriterionTypeFormatter {
+        @Override
+        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
+            final VlanIdCriterion vlanIdCriterion =
+                    (VlanIdCriterion) criterion;
+            return root.put(CriterionCodec.INNER_VLAN_ID, vlanIdCriterion.vlanId().toShort());
+        }
+    }
+
+    private static class FormatInnerVlanPcp implements CriterionTypeFormatter {
+        @Override
+        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
+            final VlanPcpCriterion vlanPcpCriterion =
+                    (VlanPcpCriterion) criterion;
+            return root.put(CriterionCodec.INNER_PRIORITY, vlanPcpCriterion.priority());
+        }
+    }
+
     private static class FormatIpDscp implements CriterionTypeFormatter {
         @Override
         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {