ONOS-635 Adding ICMPv6 type and code builder for HostMonitor.

aovid duplicate call of toString.

Apply changes to FlowEntryBuilder and FlowModBuilder as well.
Fix missing break; issue.

Change-Id: I1a2e59ca943bbcc9677b9fc0cb9eb2f7cb3d7aa3
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
index 756fdd7..e5f552d 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
@@ -194,6 +194,16 @@
         }
 
         @Override
+        public Builder matchIcmpv6Type(Byte icmpv6Type) {
+            return add(Criteria.matchIcmpv6Type(icmpv6Type));
+        }
+
+        @Override
+        public Builder matchIcmpv6Code(Byte icmpv6Code) {
+            return add(Criteria.matchIcmpv6Code(icmpv6Code));
+        }
+
+        @Override
         public Builder matchMplsLabel(Integer mplsLabel) {
             return add(Criteria.matchMplsLabel(mplsLabel));
         }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
index 267fb51..e483043 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
@@ -163,6 +163,22 @@
         public Builder matchIPv6Dst(IpPrefix ip);
 
         /**
+         * Matches a ICMPv6 type.
+         *
+         * @param icmpv6Type a ICMPv6 type
+         * @return a selection builder
+         */
+        public Builder matchIcmpv6Type(Byte icmpv6Type);
+
+        /**
+         * Matches a ICMPv6 code.
+         *
+         * @param icmpv6Code a ICMPv6 code
+         * @return a selection builder
+         */
+        public Builder matchIcmpv6Code(Byte icmpv6Code);
+
+        /**
          * Matches on a MPLS label .
          * @param mplsLabel a MPLS label.
          * @return a selection builder
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index e725143..5ef50c4 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -167,6 +167,26 @@
         return new IPCriterion(ip, Type.IPV6_DST);
     }
 
+    /*
+     * Creates a match on ICMPv6 type field using the specified value.
+     *
+     * @param icmpv6Type ICMPv6 type
+     * @return match criterion
+     */
+    public static Criterion matchIcmpv6Type(Byte icmpv6Type) {
+        return new Icmpv6TypeCriterion(icmpv6Type);
+    }
+
+    /**
+     * Creates a match on ICMPv6 code field using the specified value.
+     *
+     * @param icmpv6Code ICMPv6 code
+     * @return match criterion
+     */
+    public static Criterion matchIcmpv6Code(Byte icmpv6Code) {
+        return new Icmpv6CodeCriterion(icmpv6Code);
+    }
+
     /**
      * Creates a match on MPLS label.
      * @param mplsLabel MPLS label
@@ -588,6 +608,96 @@
     }
 
     /**
+     * Implementation of ICMPv6 type criterion.
+     */
+    public static final class Icmpv6TypeCriterion implements Criterion {
+
+        private final Byte icmpv6Type;
+
+        public Icmpv6TypeCriterion(Byte icmpv6Type) {
+            this.icmpv6Type = icmpv6Type;
+        }
+
+        @Override
+        public Type type() {
+            return Type.ICMPV6_TYPE;
+        }
+
+        public Byte icmpv6Type() {
+            return icmpv6Type;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("icmpv6Type", icmpv6Type & 0xff).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(icmpv6Type, type());
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof Icmpv6TypeCriterion) {
+                Icmpv6TypeCriterion that = (Icmpv6TypeCriterion) obj;
+                return Objects.equals(icmpv6Type, that.icmpv6Type) &&
+                        Objects.equals(this.type(), that.type());
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Implementation of ICMPv6 code criterion.
+     */
+    public static final class Icmpv6CodeCriterion implements Criterion {
+
+        private final Byte icmpv6Code;
+
+        public Icmpv6CodeCriterion(Byte icmpv6Code) {
+            this.icmpv6Code = icmpv6Code;
+        }
+
+        @Override
+        public Type type() {
+            return Type.ICMPV6_CODE;
+        }
+
+        public Byte icmpv6Code() {
+            return icmpv6Code;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("icmpv6Code", icmpv6Code & 0xff).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(icmpv6Code, type());
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof Icmpv6CodeCriterion) {
+                Icmpv6CodeCriterion that = (Icmpv6CodeCriterion) obj;
+                return Objects.equals(icmpv6Code, that.icmpv6Code) &&
+                        Objects.equals(this.type(), that.type());
+            }
+            return false;
+        }
+    }
+
+    /**
      * Implementation of MPLS tag criterion.
      */
     public static final class MplsCriterion implements Criterion {
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 3ea2efa..576c003 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
@@ -428,6 +428,14 @@
                 }
                 builder.matchIPv6Src(sipv6);
                 break;
+            case ICMPV6_TYPE:
+                byte icmpv6type = (byte) match.get(MatchField.ICMPV6_TYPE).getValue();
+                builder.matchIcmpv6Type(icmpv6type);
+                break;
+            case ICMPV6_CODE:
+                byte icmpv6code = (byte) match.get(MatchField.ICMPV6_CODE).getValue();
+                builder.matchIcmpv6Code(icmpv6code);
+                break;
             case ARP_OP:
             case ARP_SHA:
             case ARP_SPA:
@@ -435,8 +443,6 @@
             case ARP_TPA:
             case ICMPV4_CODE:
             case ICMPV4_TYPE:
-            case ICMPV6_CODE:
-            case ICMPV6_TYPE:
             case IN_PHY_PORT:
             case IPV6_FLABEL:
             case IPV6_ND_SLL:
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
index 58a5720..78efee2 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -31,6 +31,8 @@
 import org.onosproject.net.flow.criteria.Criteria.TcpPortCriterion;
 import org.onosproject.net.flow.criteria.Criteria.VlanIdCriterion;
 import org.onosproject.net.flow.criteria.Criteria.VlanPcpCriterion;
+import org.onosproject.net.flow.criteria.Criteria.Icmpv6TypeCriterion;
+import org.onosproject.net.flow.criteria.Criteria.Icmpv6CodeCriterion;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
@@ -254,6 +256,16 @@
                             IPv6Address.of(ip6Prefix.address().toString()));
                 }
                 break;
+            case ICMPV6_TYPE:
+                Icmpv6TypeCriterion icmpv6type = (Icmpv6TypeCriterion) c;
+                mBuilder.setExact(MatchField.ICMPV6_TYPE,
+                        U8.of(icmpv6type.icmpv6Type().byteValue()));
+                break;
+            case ICMPV6_CODE:
+                Icmpv6CodeCriterion icmpv6code = (Icmpv6CodeCriterion) c;
+                mBuilder.setExact(MatchField.ICMPV6_CODE,
+                        U8.of(icmpv6code.icmpv6Code().byteValue()));
+                break;
             case ARP_OP:
             case ARP_SHA:
             case ARP_SPA:
@@ -261,8 +273,6 @@
             case ARP_TPA:
             case ICMPV4_CODE:
             case ICMPV4_TYPE:
-            case ICMPV6_CODE:
-            case ICMPV6_TYPE:
             case IN_PHY_PORT:
             case IPV6_EXTHDR:
             case IPV6_FLABEL: