Implement some of the missing IPv6 flowmod treatments

Work toward ONOS-509

The following treatments are added/implemented:
  - IPV6_SRC
  - IPV6_DST
  - IPV6_FLABEL

Also:
 - Renamed L3ModificationInstruction.L3SubType.IP_SRC and IP_DST
   to IPV4_SRC and IPV4_DST (for naming consistency).
 - Few minor fixes in related code: Javadocs, comments, log messages,
   and IP address usage.

Change-Id: I551056f767a37e7cb6ae7d79f4a3929183500b57
diff --git a/web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java b/web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
index 913fc8b..3957beb 100644
--- a/web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
+++ b/web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
@@ -117,13 +117,22 @@
     private void encodeL3(ObjectNode result, L3ModificationInstruction instruction) {
         result.put("subtype", instruction.subtype().name());
         switch (instruction.subtype()) {
-            case IP_SRC:
-            case IP_DST:
+            case IPV4_SRC:
+            case IPV4_DST:
+            case IPV6_SRC:
+            case IPV6_DST:
                 final L3ModificationInstruction.ModIPInstruction modIPInstruction =
                         (L3ModificationInstruction.ModIPInstruction) instruction;
                 result.put("ip", modIPInstruction.ip().toString());
                 break;
 
+            case IPV6_FLABEL:
+                final L3ModificationInstruction.ModIPv6FlowLabelInstruction
+                    modFlowLabelInstruction =
+                        (L3ModificationInstruction.ModIPv6FlowLabelInstruction) instruction;
+                result.put("flowLabel", modFlowLabelInstruction.flowLabel());
+                break;
+
             default:
                 log.info("Cannot convert L3 subtype of {}", instruction.subtype());
                 break;
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java b/web/api/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
index 8bf4439..923573e 100644
--- a/web/api/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
+++ b/web/api/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
@@ -17,8 +17,8 @@
 
 import org.junit.Before;
 import org.junit.Test;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onosproject.codec.CodecContext;
@@ -144,11 +144,11 @@
     }
 
     /**
-     * Tests the encoding of mod ip instructions.
+     * Tests the encoding of mod IPv4 src instructions.
      */
     @Test
-    public void modIPInstructionTest() {
-        final IpAddress ip = IpPrefix.valueOf("1.2.3.4/24").address();
+    public void modIPSrcInstructionTest() {
+        final Ip4Address ip = Ip4Address.valueOf("1.2.3.4");
         final L3ModificationInstruction.ModIPInstruction instruction =
                 (L3ModificationInstruction.ModIPInstruction)
                         Instructions.modL3Src(ip);
@@ -158,6 +158,62 @@
     }
 
     /**
+     * Tests the encoding of mod IPv4 dst instructions.
+     */
+    @Test
+    public void modIPDstInstructionTest() {
+        final Ip4Address ip = Ip4Address.valueOf("1.2.3.4");
+        final L3ModificationInstruction.ModIPInstruction instruction =
+                (L3ModificationInstruction.ModIPInstruction)
+                        Instructions.modL3Dst(ip);
+        final ObjectNode instructionJson =
+                instructionCodec.encode(instruction, context);
+        assertThat(instructionJson, matchesInstruction(instruction));
+    }
+
+    /**
+     * Tests the encoding of mod IPv6 src instructions.
+     */
+    @Test
+    public void modIPv6SrcInstructionTest() {
+        final Ip6Address ip = Ip6Address.valueOf("1111::2222");
+        final L3ModificationInstruction.ModIPInstruction instruction =
+                (L3ModificationInstruction.ModIPInstruction)
+                        Instructions.modL3IPv6Src(ip);
+        final ObjectNode instructionJson =
+                instructionCodec.encode(instruction, context);
+        assertThat(instructionJson, matchesInstruction(instruction));
+    }
+
+    /**
+     * Tests the encoding of mod IPv6 dst instructions.
+     */
+    @Test
+    public void modIPv6DstInstructionTest() {
+        final Ip6Address ip = Ip6Address.valueOf("1111::2222");
+        final L3ModificationInstruction.ModIPInstruction instruction =
+                (L3ModificationInstruction.ModIPInstruction)
+                        Instructions.modL3IPv6Dst(ip);
+        final ObjectNode instructionJson =
+                instructionCodec.encode(instruction, context);
+        assertThat(instructionJson, matchesInstruction(instruction));
+    }
+
+    /**
+     * Tests the encoding of mod IPv6 flow label instructions.
+     */
+    @Test
+    public void modIPv6FlowLabelInstructionTest() {
+        final int flowLabel = 0xfffff;
+        final L3ModificationInstruction.ModIPv6FlowLabelInstruction instruction =
+                (L3ModificationInstruction.ModIPv6FlowLabelInstruction)
+                        Instructions.modL3IPv6FlowLabel(flowLabel);
+        final ObjectNode instructionJson =
+                instructionCodec.encode(instruction, context);
+        assertThat(instructionJson, matchesInstruction(instruction));
+    }
+
+    /**
      * Tests the encoding of mod MPLS label instructions.
      */
     @Test
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java b/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
index 0086255..72d3e41 100644
--- a/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
+++ b/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
@@ -41,6 +41,7 @@
      * Matches the contents of a push header instruction.
      *
      * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
      * @return true if contents match, false otherwise
      */
     private boolean matchPushHeaderInstruction(JsonNode instructionJson,
@@ -77,6 +78,7 @@
      * Matches the contents of an output instruction.
      *
      * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
      * @return true if contents match, false otherwise
      */
     private boolean matchOutputInstruction(JsonNode instructionJson,
@@ -102,6 +104,7 @@
      * Matches the contents of a mod lambda instruction.
      *
      * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
      * @return true if contents match, false otherwise
      */
     private boolean matchModLambdaInstruction(JsonNode instructionJson,
@@ -133,6 +136,7 @@
      * Matches the contents of a mod Ethernet instruction.
      *
      * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
      * @return true if contents match, false otherwise
      */
     private boolean matchModEtherInstruction(JsonNode instructionJson,
@@ -165,6 +169,7 @@
      * Matches the contents of a mod vlan id instruction.
      *
      * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
      * @return true if contents match, false otherwise
      */
     private boolean matchModVlanIdInstruction(JsonNode instructionJson,
@@ -197,6 +202,7 @@
      * Matches the contents of a mod vlan pcp instruction.
      *
      * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
      * @return true if contents match, false otherwise
      */
     private boolean matchModVlanPcpInstruction(JsonNode instructionJson,
@@ -229,6 +235,7 @@
      * Matches the contents of a mod ip instruction.
      *
      * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
      * @return true if contents match, false otherwise
      */
     private boolean matchModIpInstruction(JsonNode instructionJson,
@@ -258,9 +265,43 @@
     }
 
     /**
+     * Matches the contents of a mod IPv6 Flow Label instruction.
+     *
+     * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
+     * @return true if contents match, false otherwise
+     */
+    private boolean matchModIPv6FlowLabelInstruction(JsonNode instructionJson,
+                                                     Description description) {
+        ModIPv6FlowLabelInstruction instructionToMatch =
+                (ModIPv6FlowLabelInstruction) instruction;
+        final String jsonSubtype = instructionJson.get("subtype").textValue();
+        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
+            description.appendText("subtype was " + jsonSubtype);
+            return false;
+        }
+
+        final String jsonType = instructionJson.get("type").textValue();
+        if (!instructionToMatch.type().name().equals(jsonType)) {
+            description.appendText("type was " + jsonType);
+            return false;
+        }
+
+        final int jsonFlowLabel = instructionJson.get("flowLabel").intValue();
+        final int flowLabel = instructionToMatch.flowLabel();
+        if (flowLabel != jsonFlowLabel) {
+            description.appendText("IPv6 flow label was " + jsonFlowLabel);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
      * Matches the contents of a mod MPLS label instruction.
      *
      * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
      * @return true if contents match, false otherwise
      */
     private boolean matchModMplsLabelInstruction(JsonNode instructionJson,
@@ -282,7 +323,7 @@
         final int jsonLabel = instructionJson.get("label").intValue();
         final int label = instructionToMatch.label();
         if (label != jsonLabel) {
-            description.appendText("ip was " + jsonLabel);
+            description.appendText("MPLS label was " + jsonLabel);
             return false;
         }
 
@@ -317,6 +358,9 @@
             return matchModVlanPcpInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModIPInstruction) {
             return matchModIpInstruction(jsonInstruction, description);
+        } else if (instruction instanceof ModIPv6FlowLabelInstruction) {
+            return matchModIPv6FlowLabelInstruction(jsonInstruction,
+                                                    description);
         } else if (instruction instanceof ModMplsLabelInstruction) {
             return matchModMplsLabelInstruction(jsonInstruction, description);
         }