Implement some of the missing Selector and Match Conditions

Work toward ONOS-509

The following match conditions are added/implemented:
 - UDP_SRC, UDP_DST
 - SCTP_SRC, SCTP_DST
 - ICMPV4_TYPE, ICMPV4_CODE
 - IPV6_FLABEL
 - IPV6_ND_TARGET
 - IPV6_ND_SLL
 - IPV6_ND_TLL

Also:
 * Renamed method
     TrafficSelector.Builder.matchInport(PortNumber port)
   to
     TrafficSelector.Builder.matchInPort(PortNumber port)
   (for consistency with the corresponding method(s) elsewhere)
 * Reordered the code for some of the existing matching conditions
   to follow the order in the OpenFlow spec, so it is easier to
   cross-reference such code.
 * Added missing Javadoc
 * Added few more Criterion.Type values as per OpenFlow spec 1.5.0

Change-Id: I7fc1656f32d8a7280c67d7827e4aa84528b0eafc
diff --git a/apps/fwd/src/main/java/org/onosproject/fwd/ReactiveForwarding.java b/apps/fwd/src/main/java/org/onosproject/fwd/ReactiveForwarding.java
index a10bfef..0cf2939 100644
--- a/apps/fwd/src/main/java/org/onosproject/fwd/ReactiveForwarding.java
+++ b/apps/fwd/src/main/java/org/onosproject/fwd/ReactiveForwarding.java
@@ -288,7 +288,7 @@
             builder.matchEthType(inPkt.getEtherType())
                     .matchEthSrc(inPkt.getSourceMAC())
                     .matchEthDst(inPkt.getDestinationMAC())
-                    .matchInport(context.inPacket().receivedFrom().port());
+                    .matchInPort(context.inPacket().receivedFrom().port());
 
             TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
             treat.setOutput(portNumber);
diff --git a/apps/optical/src/main/java/org/onosproject/optical/testapp/LambdaForwarding.java b/apps/optical/src/main/java/org/onosproject/optical/testapp/LambdaForwarding.java
index f88ad5e..2f29d7e 100644
--- a/apps/optical/src/main/java/org/onosproject/optical/testapp/LambdaForwarding.java
+++ b/apps/optical/src/main/java/org/onosproject/optical/testapp/LambdaForwarding.java
@@ -107,21 +107,21 @@
         case 1:
             inport = 10;
             outport = 20;
-            sbuilder.matchInport(PortNumber.portNumber(inport));
+            sbuilder.matchInPort(PortNumber.portNumber(inport));
             tbuilder.setOutput(PortNumber.portNumber(outport)).setLambda(lambda);
             break;
         case 2:
             inport = 21;
             outport = 11;
             sbuilder.matchLambda(lambda).
-                    matchInport(PortNumber.portNumber(inport)); // match sigtype
+                    matchInPort(PortNumber.portNumber(inport)); // match sigtype
             tbuilder.setOutput(PortNumber.portNumber(outport));
             break;
         case 3:
             inport = 30;
             outport = 31;
             sbuilder.matchLambda(lambda).
-                    matchInport(PortNumber.portNumber(inport));
+                    matchInPort(PortNumber.portNumber(inport));
             tbuilder.setOutput(PortNumber.portNumber(outport)).setLambda(lambda);
             break;
         default:
diff --git a/apps/optical/src/main/java/org/onosproject/optical/testapp/MPLSForwarding.java b/apps/optical/src/main/java/org/onosproject/optical/testapp/MPLSForwarding.java
index 670bf9f..bea39da 100644
--- a/apps/optical/src/main/java/org/onosproject/optical/testapp/MPLSForwarding.java
+++ b/apps/optical/src/main/java/org/onosproject/optical/testapp/MPLSForwarding.java
@@ -106,7 +106,7 @@
 
         switch (switchNumber) {
             case 1:
-                sbuilder.matchInport(PortNumber.portNumber(inport));
+                sbuilder.matchInPort(PortNumber.portNumber(inport));
                 tbuilder.setOutput(PortNumber.portNumber(outport))
                         .pushMpls()
                         .setMpls(mplsLabel);
@@ -114,13 +114,13 @@
             case 2:
                 sbuilder.matchMplsLabel(mplsLabel)
                         .matchEthType(Ethernet.MPLS_UNICAST)
-                        .matchInport(PortNumber.portNumber(inport));
+                        .matchInPort(PortNumber.portNumber(inport));
                 tbuilder.setOutput(PortNumber.portNumber(outport));
                 break;
             case 3:
                 sbuilder.matchMplsLabel(mplsLabel)
                         .matchEthType(Ethernet.MPLS_UNICAST)
-                        .matchInport(PortNumber.portNumber(inport));
+                        .matchInPort(PortNumber.portNumber(inport));
                 tbuilder.popMpls().setOutput(PortNumber.portNumber(outport));
                 break;
             default:
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 e5f552d..21b1832 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
@@ -24,6 +24,7 @@
 import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip6Address;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 
@@ -129,22 +130,22 @@
         }
 
         @Override
-        public Builder matchInport(PortNumber port) {
+        public Builder matchInPort(PortNumber port) {
             return add(Criteria.matchInPort(port));
         }
 
         @Override
-        public Builder matchEthSrc(MacAddress addr) {
-            return add(Criteria.matchEthSrc(addr));
-        }
-
-        @Override
         public Builder matchEthDst(MacAddress addr) {
             return add(Criteria.matchEthDst(addr));
         }
 
         @Override
-        public Builder matchEthType(short ethType) {
+        public Builder matchEthSrc(MacAddress addr) {
+            return add(Criteria.matchEthSrc(addr));
+        }
+
+        @Override
+        public Builder matchEthType(Short ethType) {
             return add(Criteria.matchEthType(ethType));
         }
 
@@ -184,6 +185,36 @@
         }
 
         @Override
+        public Builder matchUdpSrc(Short udpPort) {
+            return add(Criteria.matchUdpSrc(udpPort));
+        }
+
+        @Override
+        public Builder matchUdpDst(Short udpPort) {
+            return add(Criteria.matchUdpDst(udpPort));
+        }
+
+        @Override
+        public Builder matchSctpSrc(Short sctpPort) {
+            return add(Criteria.matchSctpSrc(sctpPort));
+        }
+
+        @Override
+        public Builder matchSctpDst(Short sctpPort) {
+            return add(Criteria.matchSctpDst(sctpPort));
+        }
+
+        @Override
+        public Builder matchIcmpType(Byte icmpType) {
+            return add(Criteria.matchIcmpType(icmpType));
+        }
+
+        @Override
+        public Builder matchIcmpCode(Byte icmpCode) {
+            return add(Criteria.matchIcmpCode(icmpCode));
+        }
+
+        @Override
         public Builder matchIPv6Src(IpPrefix ip) {
             return add(Criteria.matchIPv6Src(ip));
         }
@@ -194,6 +225,11 @@
         }
 
         @Override
+        public Builder matchIPv6FlowLabel(Integer flowLabel) {
+            return add(Criteria.matchIPv6FlowLabel(flowLabel));
+        }
+
+        @Override
         public Builder matchIcmpv6Type(Byte icmpv6Type) {
             return add(Criteria.matchIcmpv6Type(icmpv6Type));
         }
@@ -204,6 +240,21 @@
         }
 
         @Override
+        public Builder matchIPv6NDTargetAddress(Ip6Address targetAddress) {
+            return add(Criteria.matchIPv6NDTargetAddress(targetAddress));
+        }
+
+        @Override
+        public Builder matchIPv6NDSourceLinkLayerAddress(MacAddress mac) {
+            return add(Criteria.matchIPv6NDSourceLinkLayerAddress(mac));
+        }
+
+        @Override
+        public Builder matchIPv6NDTargetLinkLayerAddress(MacAddress mac) {
+            return add(Criteria.matchIPv6NDTargetLinkLayerAddress(mac));
+        }
+
+        @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 e483043..e6fdeb2 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
@@ -20,6 +20,7 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip6Address;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 
@@ -64,15 +65,7 @@
          * @param port the inport
          * @return a selection builder
          */
-        public Builder matchInport(PortNumber port);
-
-        /**
-         * Matches a l2 src address.
-         *
-         * @param addr a l2 address
-         * @return a selection builder
-         */
-        public Builder matchEthSrc(MacAddress addr);
+        public Builder matchInPort(PortNumber port);
 
         /**
          * Matches a l2 dst address.
@@ -83,12 +76,20 @@
         public Builder matchEthDst(MacAddress addr);
 
         /**
+         * Matches a l2 src address.
+         *
+         * @param addr a l2 address
+         * @return a selection builder
+         */
+        public Builder matchEthSrc(MacAddress addr);
+
+        /**
          * Matches the ethernet type.
          *
          * @param ethType an ethernet type
          * @return a selection builder
          */
-        public Builder matchEthType(short ethType);
+        public Builder matchEthType(Short ethType);
 
         /**
          * Matches the vlan id.
@@ -147,6 +148,54 @@
         public Builder matchTcpDst(Short tcpPort);
 
         /**
+         * Matches an UDP source port number.
+         *
+         * @param udpPort an UDP source port number
+         * @return a selection builder
+         */
+        public Builder matchUdpSrc(Short udpPort);
+
+        /**
+         * Matches an UDP destination port number.
+         *
+         * @param udpPort an UDP destination port number
+         * @return a selection builder
+         */
+        public Builder matchUdpDst(Short udpPort);
+
+        /**
+         * Matches a SCTP source port number.
+         *
+         * @param sctpPort a SCTP source port number
+         * @return a selection builder
+         */
+        public Builder matchSctpSrc(Short sctpPort);
+
+        /**
+         * Matches a SCTP destination port number.
+         *
+         * @param sctpPort a SCTP destination port number
+         * @return a selection builder
+         */
+        public Builder matchSctpDst(Short sctpPort);
+
+        /**
+         * Matches an ICMP type.
+         *
+         * @param icmpType an ICMP type
+         * @return a selection builder
+         */
+        public Builder matchIcmpType(Byte icmpType);
+
+        /**
+         * Matches an ICMP code.
+         *
+         * @param icmpCode an ICMP code
+         * @return a selection builder
+         */
+        public Builder matchIcmpCode(Byte icmpCode);
+
+        /**
          * Matches a l3 IPv6 address.
          *
          * @param ip a l3 IPv6 address
@@ -163,23 +212,56 @@
         public Builder matchIPv6Dst(IpPrefix ip);
 
         /**
-         * Matches a ICMPv6 type.
+         * Matches an IPv6 flow label.
          *
-         * @param icmpv6Type a ICMPv6 type
+         * @param flowLabel an IPv6 flow label
+         * @return a selection builder
+         */
+        public Builder matchIPv6FlowLabel(Integer flowLabel);
+
+        /**
+         * Matches an ICMPv6 type.
+         *
+         * @param icmpv6Type an ICMPv6 type
          * @return a selection builder
          */
         public Builder matchIcmpv6Type(Byte icmpv6Type);
 
         /**
-         * Matches a ICMPv6 code.
+         * Matches an ICMPv6 code.
          *
-         * @param icmpv6Code a ICMPv6 code
+         * @param icmpv6Code an ICMPv6 code
          * @return a selection builder
          */
         public Builder matchIcmpv6Code(Byte icmpv6Code);
 
         /**
-         * Matches on a MPLS label .
+         * Matches an IPv6 Neighbor Discovery target address.
+         *
+         * @param targetAddress an IPv6 Neighbor Discovery target address
+         * @return a selection builder
+         */
+        public Builder matchIPv6NDTargetAddress(Ip6Address targetAddress);
+
+        /**
+         * Matches an IPv6 Neighbor Discovery source link-layer address.
+         *
+         * @param mac an IPv6 Neighbor Discovery source link-layer address
+         * @return a selection builder
+         */
+        public Builder matchIPv6NDSourceLinkLayerAddress(MacAddress mac);
+
+        /**
+         * Matches an IPv6 Neighbor Discovery target link-layer address.
+         *
+         * @param mac an IPv6 Neighbor Discovery target link-layer address
+         * @return a selection builder
+         */
+        public Builder matchIPv6NDTargetLinkLayerAddress(MacAddress mac);
+
+        /**
+         * Matches on a MPLS label.
+         *
          * @param mplsLabel a MPLS label.
          * @return a selection builder
          */
@@ -208,5 +290,4 @@
          */
         TrafficSelector build();
     }
-
 }
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 5ef50c4..d4ec124 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
@@ -21,6 +21,7 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.criteria.Criterion.Type;
 import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip6Address;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 
@@ -46,17 +47,6 @@
     }
 
     /**
-     * Creates a match on ETH_SRC field using the specified value. This value
-     * may be a wildcard mask.
-     *
-     * @param mac MAC address value or wildcard mask
-     * @return match criterion
-     */
-    public static Criterion matchEthSrc(MacAddress mac) {
-        return new EthCriterion(mac, Type.ETH_SRC);
-    }
-
-    /**
      * Creates a match on ETH_DST field using the specified value. This value
      * may be a wildcard mask.
      *
@@ -68,6 +58,17 @@
     }
 
     /**
+     * Creates a match on ETH_SRC field using the specified value. This value
+     * may be a wildcard mask.
+     *
+     * @param mac MAC address value or wildcard mask
+     * @return match criterion
+     */
+    public static Criterion matchEthSrc(MacAddress mac) {
+        return new EthCriterion(mac, Type.ETH_SRC);
+    }
+
+    /**
      * Creates a match on ETH_TYPE field using the specified value.
      *
      * @param ethType eth type value
@@ -148,6 +149,67 @@
     }
 
     /**
+     * Creates a match on UDP source port field using the specified value.
+     *
+     * @param udpPort UDP source port
+     * @return match criterion
+     */
+    public static Criterion matchUdpSrc(Short udpPort) {
+        return new UdpPortCriterion(udpPort, Type.UDP_SRC);
+    }
+
+    /**
+     * Creates a match on UDP destination port field using the specified value.
+     *
+     * @param udpPort UDP destination port
+     * @return match criterion
+     */
+    public static Criterion matchUdpDst(Short udpPort) {
+        return new UdpPortCriterion(udpPort, Type.UDP_DST);
+    }
+
+    /**
+     * Creates a match on SCTP source port field using the specified value.
+     *
+     * @param sctpPort SCTP source port
+     * @return match criterion
+     */
+    public static Criterion matchSctpSrc(Short sctpPort) {
+        return new SctpPortCriterion(sctpPort, Type.SCTP_SRC);
+    }
+
+    /**
+     * Creates a match on SCTP destination port field using the specified
+     * value.
+     *
+     * @param sctpPort SCTP destination port
+     * @return match criterion
+     */
+    public static Criterion matchSctpDst(Short sctpPort) {
+        return new SctpPortCriterion(sctpPort, Type.SCTP_DST);
+    }
+
+    /**
+     * Creates a match on ICMP type field using the specified value.
+     *
+     * @param icmpType ICMP type
+     * @return match criterion
+     */
+    public static Criterion matchIcmpType(Byte icmpType) {
+        return new IcmpTypeCriterion(icmpType);
+    }
+
+    /**
+     * Creates a match on ICMP code field using the specified value.
+     *
+     * @param icmpCode ICMP code
+     * @return match criterion
+     */
+    public static Criterion matchIcmpCode(Byte icmpCode) {
+        return new IcmpCodeCriterion(icmpCode);
+    }
+
+    /**
      * Creates a match on IPv6 source field using the specified value.
      *
      * @param ip ipv6 source value
@@ -160,14 +222,24 @@
     /**
      * Creates a match on IPv6 destination field using the specified value.
      *
-     * @param ip ipv6 source value
+     * @param ip ipv6 destination value
      * @return match criterion
      */
     public static Criterion matchIPv6Dst(IpPrefix ip) {
         return new IPCriterion(ip, Type.IPV6_DST);
     }
 
-    /*
+    /**
+     * Creates a match on IPv6 flow label field using the specified value.
+     *
+     * @param flowLabel IPv6 flow label
+     * @return match criterion
+     */
+    public static Criterion matchIPv6FlowLabel(Integer flowLabel) {
+        return new IPv6FlowLabelCriterion(flowLabel);
+    }
+
+    /**
      * Creates a match on ICMPv6 type field using the specified value.
      *
      * @param icmpv6Type ICMPv6 type
@@ -188,11 +260,44 @@
     }
 
     /**
+     * Creates a match on IPv6 Neighbor Discovery target address using the
+     * specified value.
+     *
+     * @param targetAddress IPv6 Neighbor Discovery target address
+     * @return match criterion
+     */
+    public static Criterion matchIPv6NDTargetAddress(Ip6Address targetAddress) {
+        return new IPv6NDTargetAddressCriterion(targetAddress);
+    }
+
+    /**
+     * Creates a match on IPv6 Neighbor Discovery source link-layer address
+     * using the specified value.
+     *
+     * @param mac IPv6 Neighbor Discovery source link-layer address
+     * @return match criterion
+     */
+    public static Criterion matchIPv6NDSourceLinkLayerAddress(MacAddress mac) {
+        return new IPv6NDLinkLayerAddressCriterion(mac, Type.IPV6_ND_SLL);
+    }
+
+    /**
+     * Creates a match on IPv6 Neighbor Discovery target link-layer address
+     * using the specified value.
+     *
+     * @param mac IPv6 Neighbor Discovery target link-layer address
+     * @return match criterion
+     */
+    public static Criterion matchIPv6NDTargetLinkLayerAddress(MacAddress mac) {
+        return new IPv6NDLinkLayerAddressCriterion(mac, Type.IPV6_ND_TLL);
+    }
+
+    /**
      * Creates a match on MPLS label.
+     *
      * @param mplsLabel MPLS label
      * @return match criterion
      */
-
     public static Criterion matchMplsLabel(Integer mplsLabel) {
         return new MplsCriterion(mplsLabel);
     }
@@ -223,6 +328,11 @@
     public static final class PortCriterion implements Criterion {
         private final PortNumber port;
 
+        /**
+         * Constructor.
+         *
+         * @param port the input port number to match
+         */
         public PortCriterion(PortNumber port) {
             this.port = port;
         }
@@ -232,6 +342,11 @@
             return Type.IN_PORT;
         }
 
+        /**
+         * Gets the input port number to match.
+         *
+         * @return the input port number to match
+         */
         public PortNumber port() {
             return this.port;
         }
@@ -260,10 +375,8 @@
             }
             return false;
         }
-
     }
 
-
     /**
      * Implementation of MAC address criterion.
      */
@@ -271,6 +384,13 @@
         private final MacAddress mac;
         private final Type type;
 
+        /**
+         * Constructor.
+         *
+         * @param mac the source or destination MAC address to match
+         * @param type the match type. Should be either Type.ETH_DST or
+         * Type.ETH_SRC
+         */
         public EthCriterion(MacAddress mac, Type type) {
             this.mac = mac;
             this.type = type;
@@ -281,6 +401,11 @@
             return this.type;
         }
 
+        /**
+         * Gets the MAC address to match.
+         *
+         * @return the MAC address to match
+         */
         public MacAddress mac() {
             return this.mac;
         }
@@ -305,22 +430,22 @@
                 EthCriterion that = (EthCriterion) obj;
                 return Objects.equals(mac, that.mac) &&
                         Objects.equals(type, that.type);
-
-
             }
             return false;
         }
-
-
     }
 
     /**
      * Implementation of Ethernet type criterion.
      */
     public static final class EthTypeCriterion implements Criterion {
-
         private final Short ethType;
 
+        /**
+         * Constructor.
+         *
+         * @param ethType the Ethernet frame type to match
+         */
         public EthTypeCriterion(Short ethType) {
             this.ethType = ethType;
         }
@@ -330,6 +455,11 @@
             return Type.ETH_TYPE;
         }
 
+        /**
+         * Gets the Ethernet frame type to match.
+         *
+         * @return the Ethernet frame type to match
+         */
         public Short ethType() {
             return ethType;
         }
@@ -360,40 +490,46 @@
             }
             return false;
         }
-
     }
 
     /**
-     * Implementation of IP address criterion.
+     * Implementation of VLAN ID criterion.
      */
-    public static final class IPCriterion implements Criterion {
+    public static final class VlanIdCriterion implements Criterion {
+        private final VlanId vlanId;
 
-        private final IpPrefix ip;
-        private final Type type;
-
-        public IPCriterion(IpPrefix ip, Type type) {
-            this.ip = ip;
-            this.type = type;
+        /**
+         * Constructor.
+         *
+         * @param vlanId the VLAN ID to match
+         */
+        public VlanIdCriterion(VlanId vlanId) {
+            this.vlanId = vlanId;
         }
 
         @Override
         public Type type() {
-            return this.type;
+            return Type.VLAN_VID;
         }
 
-        public IpPrefix ip() {
-            return this.ip;
+        /**
+         * Gets the VLAN ID to match.
+         *
+         * @return the VLAN ID to match
+         */
+        public VlanId vlanId() {
+            return vlanId;
         }
 
         @Override
         public String toString() {
             return toStringHelper(type().toString())
-                    .add("ip", ip).toString();
+                    .add("vlanId", vlanId).toString();
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(type, ip);
+            return Objects.hash(type(), vlanId);
         }
 
         @Override
@@ -401,25 +537,80 @@
             if (this == obj) {
                 return true;
             }
-            if (obj instanceof IPCriterion) {
-                IPCriterion that = (IPCriterion) obj;
-                return Objects.equals(ip, that.ip) &&
-                        Objects.equals(type, that.type);
-
-
+            if (obj instanceof VlanIdCriterion) {
+                VlanIdCriterion that = (VlanIdCriterion) obj;
+                return Objects.equals(vlanId, that.vlanId) &&
+                        Objects.equals(this.type(), that.type());
             }
             return false;
         }
+    }
 
+    /**
+     * Implementation of VLAN priority criterion.
+     */
+    public static final class VlanPcpCriterion implements Criterion {
+        private final Byte vlanPcp;
+
+        /**
+         * Constructor.
+         *
+         * @param vlanPcp the VLAN priority to match
+         */
+        public VlanPcpCriterion(Byte vlanPcp) {
+            this.vlanPcp = vlanPcp;
+        }
+
+        @Override
+        public Type type() {
+            return Type.VLAN_PCP;
+        }
+
+        /**
+         * Gets the VLAN priority to match.
+         *
+         * @return the VLAN priority to match
+         */
+        public Byte priority() {
+            return vlanPcp;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("priority", Long.toHexString(vlanPcp)).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type(), vlanPcp);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof VlanPcpCriterion) {
+                VlanPcpCriterion that = (VlanPcpCriterion) obj;
+                return Objects.equals(vlanPcp, that.vlanPcp) &&
+                        Objects.equals(this.type(), that.type());
+            }
+            return false;
+        }
     }
 
     /**
      * Implementation of Internet Protocol Number criterion.
      */
     public static final class IPProtocolCriterion implements Criterion {
-
         private final Byte proto;
 
+        /**
+         * Constructor.
+         *
+         * @param protocol the IP protocol to match (e.g., TCP=6, UDP=17).
+         */
         public IPProtocolCriterion(Byte protocol) {
             this.proto = protocol;
         }
@@ -429,6 +620,11 @@
             return Type.IP_PROTO;
         }
 
+        /**
+         * Gets the IP protocol to match.
+         *
+         * @return the IP protocol to match
+         */
         public Byte protocol() {
             return proto;
         }
@@ -453,43 +649,53 @@
             if (obj instanceof IPProtocolCriterion) {
                 IPProtocolCriterion that = (IPProtocolCriterion) obj;
                 return Objects.equals(proto, that.proto);
-
-
             }
             return false;
         }
-
     }
 
     /**
-     * Implementation of VLAN priority criterion.
+     * Implementation of IP address criterion.
      */
-    public static final class VlanPcpCriterion implements Criterion {
+    public static final class IPCriterion implements Criterion {
+        private final IpPrefix ip;
+        private final Type type;
 
-        private final Byte vlanPcp;
-
-        public VlanPcpCriterion(Byte vlanPcp) {
-            this.vlanPcp = vlanPcp;
+        /**
+         * Constructor.
+         *
+         * @param ip the IP prefix to match. Could be either IPv4 or IPv6
+         * @param type the match type. Should be one of the following:
+         * Type.IPV4_SRC, Type.IPV4_DST, Type.IPV6_SRC, Type.IPV6_DST
+         */
+        public IPCriterion(IpPrefix ip, Type type) {
+            this.ip = ip;
+            this.type = type;
         }
 
         @Override
         public Type type() {
-            return Type.VLAN_PCP;
+            return this.type;
         }
 
-        public Byte priority() {
-            return vlanPcp;
+        /**
+         * Gets the IP prefix to match.
+         *
+         * @return the IP prefix to match
+         */
+        public IpPrefix ip() {
+            return this.ip;
         }
 
         @Override
         public String toString() {
             return toStringHelper(type().toString())
-                    .add("pcp", Long.toHexString(vlanPcp)).toString();
+                    .add("ip", ip).toString();
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(type(), vlanPcp);
+            return Objects.hash(type, ip);
         }
 
         @Override
@@ -497,75 +703,29 @@
             if (this == obj) {
                 return true;
             }
-            if (obj instanceof VlanPcpCriterion) {
-                VlanPcpCriterion that = (VlanPcpCriterion) obj;
-                return Objects.equals(vlanPcp, that.vlanPcp) &&
-                        Objects.equals(this.type(), that.type());
-
-
+            if (obj instanceof IPCriterion) {
+                IPCriterion that = (IPCriterion) obj;
+                return Objects.equals(ip, that.ip) &&
+                        Objects.equals(type, that.type);
             }
             return false;
         }
-
-    }
-
-    /**
-     * Implementation of VLAN ID criterion.
-     */
-    public static final class VlanIdCriterion implements Criterion {
-
-
-        private final VlanId vlanId;
-
-        public VlanIdCriterion(VlanId vlanId) {
-            this.vlanId = vlanId;
-        }
-
-        @Override
-        public Type type() {
-            return Type.VLAN_VID;
-        }
-
-        public VlanId vlanId() {
-            return vlanId;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("id", vlanId).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), vlanId);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof VlanIdCriterion) {
-                VlanIdCriterion that = (VlanIdCriterion) obj;
-                return Objects.equals(vlanId, that.vlanId) &&
-                        Objects.equals(this.type(), that.type());
-
-
-            }
-            return false;
-        }
-
     }
 
     /**
      * Implementation of TCP port criterion.
      */
     public static final class TcpPortCriterion implements Criterion {
-
         private final Short tcpPort;
         private final Type type;
 
+        /**
+         * Constructor.
+         *
+         * @param tcpPort the TCP port to match
+         * @param type the match type. Should be either Type.TCP_SRC or
+         * Type.TCP_DST
+         */
         public TcpPortCriterion(Short tcpPort, Type type) {
             this.tcpPort = tcpPort;
             this.type = type;
@@ -576,6 +736,11 @@
             return this.type;
         }
 
+        /**
+         * Gets the TCP port to match.
+         *
+         * @return the TCP port to match
+         */
         public Short tcpPort() {
             return this.tcpPort;
         }
@@ -600,8 +765,285 @@
                 TcpPortCriterion that = (TcpPortCriterion) obj;
                 return Objects.equals(tcpPort, that.tcpPort) &&
                         Objects.equals(type, that.type);
+            }
+            return false;
+        }
+    }
 
+    /**
+     * Implementation of UDP port criterion.
+     */
+    public static final class UdpPortCriterion implements Criterion {
+        private final Short udpPort;
+        private final Type type;
 
+        /**
+         * Constructor.
+         *
+         * @param udpPort the UDP port to match
+         * @param type the match type. Should be either Type.UDP_SRC or
+         * Type.UDP_DST
+         */
+        public UdpPortCriterion(Short udpPort, Type type) {
+            this.udpPort = udpPort;
+            this.type = type;
+        }
+
+        @Override
+        public Type type() {
+            return this.type;
+        }
+
+        /**
+         * Gets the UDP port to match.
+         *
+         * @return the UDP port to match
+         */
+        public Short udpPort() {
+            return this.udpPort;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("udpPort", udpPort & 0xffff).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, udpPort);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof UdpPortCriterion) {
+                UdpPortCriterion that = (UdpPortCriterion) obj;
+                return Objects.equals(udpPort, that.udpPort) &&
+                        Objects.equals(type, that.type);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Implementation of SCTP port criterion.
+     */
+    public static final class SctpPortCriterion implements Criterion {
+        private final Short sctpPort;
+        private final Type type;
+
+        /**
+         * Constructor.
+         *
+         * @param sctpPort the SCTP port to match
+         * @param type the match type. Should be either Type.SCTP_SRC or
+         * Type.SCTP_DST
+         */
+        public SctpPortCriterion(Short sctpPort, Type type) {
+            this.sctpPort = sctpPort;
+            this.type = type;
+        }
+
+        @Override
+        public Type type() {
+            return this.type;
+        }
+
+        /**
+         * Gets the SCTP port to match.
+         *
+         * @return the SCTP port to match
+         */
+        public Short sctpPort() {
+            return this.sctpPort;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("sctpPort", sctpPort & 0xffff).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, sctpPort);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof SctpPortCriterion) {
+                SctpPortCriterion that = (SctpPortCriterion) obj;
+                return Objects.equals(sctpPort, that.sctpPort) &&
+                        Objects.equals(type, that.type);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Implementation of ICMP type criterion.
+     */
+    public static final class IcmpTypeCriterion implements Criterion {
+        private final Byte icmpType;
+
+        /**
+         * Constructor.
+         *
+         * @param icmpType the ICMP type to match
+         */
+        public IcmpTypeCriterion(Byte icmpType) {
+            this.icmpType = icmpType;
+        }
+
+        @Override
+        public Type type() {
+            return Type.ICMPV4_TYPE;
+        }
+
+        /**
+         * Gets the ICMP type to match.
+         *
+         * @return the ICMP type to match
+         */
+        public Byte icmpType() {
+            return icmpType;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("icmpType", icmpType & 0xff).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type(), icmpType);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof IcmpTypeCriterion) {
+                IcmpTypeCriterion that = (IcmpTypeCriterion) obj;
+                return Objects.equals(icmpType, that.icmpType) &&
+                        Objects.equals(this.type(), that.type());
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Implementation of ICMP code criterion.
+     */
+    public static final class IcmpCodeCriterion implements Criterion {
+        private final Byte icmpCode;
+
+        /**
+         * Constructor.
+         *
+         * @param icmpCode the ICMP code to match
+         */
+        public IcmpCodeCriterion(Byte icmpCode) {
+            this.icmpCode = icmpCode;
+        }
+
+        @Override
+        public Type type() {
+            return Type.ICMPV4_CODE;
+        }
+
+        /**
+         * Gets the ICMP code to match.
+         *
+         * @return the ICMP code to match
+         */
+        public Byte icmpCode() {
+            return icmpCode;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("icmpCode", icmpCode & 0xff).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type(), icmpCode);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof IcmpCodeCriterion) {
+                IcmpCodeCriterion that = (IcmpCodeCriterion) obj;
+                return Objects.equals(icmpCode, that.icmpCode) &&
+                        Objects.equals(this.type(), that.type());
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Implementation of IPv6 Flow Label criterion (RFC 6437).
+     */
+    public static final class IPv6FlowLabelCriterion implements Criterion {
+        private static final int FLOW_LABEL_MASK = 0xfffff;
+        private final Integer flowLabel;        // IPv6 flow label: 20 bits
+
+        /**
+         * Constructor.
+         *
+         * @param flowLabel the IPv6 flow label to match
+         */
+        public IPv6FlowLabelCriterion(Integer flowLabel) {
+            this.flowLabel = flowLabel & FLOW_LABEL_MASK;
+        }
+
+        @Override
+        public Type type() {
+            return Type.IPV6_FLABEL;
+        }
+
+        /**
+         * Gets the IPv6 flow label to match.
+         *
+         * @return the IPv6 flow label to match
+         */
+        public Integer flowLabel() {
+            return flowLabel;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("flowLabel", flowLabel).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type(), flowLabel);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof IPv6FlowLabelCriterion) {
+                IPv6FlowLabelCriterion that = (IPv6FlowLabelCriterion) obj;
+                return Objects.equals(flowLabel, that.flowLabel) &&
+                        Objects.equals(this.type(), that.type());
             }
             return false;
         }
@@ -611,9 +1053,13 @@
      * Implementation of ICMPv6 type criterion.
      */
     public static final class Icmpv6TypeCriterion implements Criterion {
-
         private final Byte icmpv6Type;
 
+        /**
+         * Constructor.
+         *
+         * @param icmpv6Type the ICMPv6 type to match
+         */
         public Icmpv6TypeCriterion(Byte icmpv6Type) {
             this.icmpv6Type = icmpv6Type;
         }
@@ -623,6 +1069,11 @@
             return Type.ICMPV6_TYPE;
         }
 
+        /**
+         * Gets the ICMPv6 type to match.
+         *
+         * @return the ICMPv6 type to match
+         */
         public Byte icmpv6Type() {
             return icmpv6Type;
         }
@@ -635,7 +1086,7 @@
 
         @Override
         public int hashCode() {
-            return Objects.hash(icmpv6Type, type());
+            return Objects.hash(type(), icmpv6Type);
         }
 
         @Override
@@ -656,9 +1107,13 @@
      * Implementation of ICMPv6 code criterion.
      */
     public static final class Icmpv6CodeCriterion implements Criterion {
-
         private final Byte icmpv6Code;
 
+        /**
+         * Constructor.
+         *
+         * @param icmpv6Code the ICMPv6 code to match
+         */
         public Icmpv6CodeCriterion(Byte icmpv6Code) {
             this.icmpv6Code = icmpv6Code;
         }
@@ -668,6 +1123,11 @@
             return Type.ICMPV6_CODE;
         }
 
+        /**
+         * Gets the ICMPv6 code to match.
+         *
+         * @return the ICMPv6 code to match
+         */
         public Byte icmpv6Code() {
             return icmpv6Code;
         }
@@ -680,7 +1140,7 @@
 
         @Override
         public int hashCode() {
-            return Objects.hash(icmpv6Code, type());
+            return Objects.hash(type(), icmpv6Code);
         }
 
         @Override
@@ -698,12 +1158,132 @@
     }
 
     /**
+     * Implementation of IPv6 Neighbor Discovery target address criterion.
+     */
+    public static final class IPv6NDTargetAddressCriterion
+                                implements Criterion {
+        private final Ip6Address targetAddress;
+
+        /**
+         * Constructor.
+         *
+         * @param targetAddress the IPv6 target address to match
+         */
+        public IPv6NDTargetAddressCriterion(Ip6Address targetAddress) {
+            this.targetAddress = targetAddress;
+        }
+
+        @Override
+        public Type type() {
+            return Type.IPV6_ND_TARGET;
+        }
+
+        /**
+         * Gets the IPv6 target address to match.
+         *
+         * @return the IPv6 target address to match
+         */
+        public Ip6Address targetAddress() {
+            return this.targetAddress;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("targetAddress", targetAddress).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type(), targetAddress);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof IPv6NDTargetAddressCriterion) {
+                IPv6NDTargetAddressCriterion that =
+                    (IPv6NDTargetAddressCriterion) obj;
+                return Objects.equals(targetAddress, that.targetAddress) &&
+                        Objects.equals(type(), that.type());
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Implementation of IPv6 Neighbor Discovery link-layer address criterion.
+     */
+    public static final class IPv6NDLinkLayerAddressCriterion
+                                implements Criterion {
+        private final MacAddress mac;
+        private final Type type;
+
+        /**
+         * Constructor.
+         *
+         * @param mac the source or destination link-layer address to match
+         * @param type the match type. Should be either Type.IPV6_ND_SLL or
+         * Type.IPV6_ND_TLL
+         */
+        public IPv6NDLinkLayerAddressCriterion(MacAddress mac, Type type) {
+            this.mac = mac;
+            this.type = type;
+        }
+
+        @Override
+        public Type type() {
+            return this.type;
+        }
+
+        /**
+         * Gets the MAC link-layer address to match.
+         *
+         * @return the MAC link-layer address to match
+         */
+        public MacAddress mac() {
+            return this.mac;
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(type().toString())
+                    .add("mac", mac).toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, mac);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof IPv6NDLinkLayerAddressCriterion) {
+                IPv6NDLinkLayerAddressCriterion that =
+                    (IPv6NDLinkLayerAddressCriterion) obj;
+                return Objects.equals(mac, that.mac) &&
+                        Objects.equals(type, that.type);
+            }
+            return false;
+        }
+    }
+
+    /**
      * Implementation of MPLS tag criterion.
      */
     public static final class MplsCriterion implements Criterion {
-
         private final Integer mplsLabel;
 
+        /**
+         * Constructor.
+         *
+         * @param mplsLabel the MPLS label to match
+         */
         public MplsCriterion(Integer mplsLabel) {
             this.mplsLabel = mplsLabel;
         }
@@ -713,6 +1293,11 @@
             return Type.MPLS_LABEL;
         }
 
+        /**
+         * Gets the MPLS label to match.
+         *
+         * @return the MPLS label to match
+         */
         public Integer label() {
             return mplsLabel;
         }
@@ -720,12 +1305,12 @@
         @Override
         public String toString() {
             return toStringHelper(type().toString())
-                    .add("mpls", mplsLabel & 0xffffffffL).toString();
+                    .add("label", mplsLabel & 0xffffffffL).toString();
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(mplsLabel, type());
+            return Objects.hash(type(), mplsLabel);
         }
 
         @Override
@@ -737,8 +1322,6 @@
                 MplsCriterion that = (MplsCriterion) obj;
                 return Objects.equals(mplsLabel, that.mplsLabel) &&
                         Objects.equals(this.type(), that.type());
-
-
             }
             return false;
         }
@@ -749,10 +1332,15 @@
      * Implementation of lambda (wavelength) criterion.
      */
     public static final class LambdaCriterion implements Criterion {
-
         private final short lambda;
         private final Type type;
 
+        /**
+         * Constructor.
+         *
+         * @param lambda the lambda (wavelength) to match
+         * @param type the match type. Should be Type.OCH_SIGID
+         */
         public LambdaCriterion(short lambda, Type type) {
             this.lambda = lambda;
             this.type = type;
@@ -763,6 +1351,11 @@
             return this.type;
         }
 
+        /**
+         * Gets the lambda (wavelength) to match.
+         *
+         * @return the lambda (wavelength) to match.
+         */
         public Short lambda() {
             return this.lambda;
         }
@@ -796,10 +1389,15 @@
      * Implementation of optical signal type criterion.
      */
     public static final class OpticalSignalTypeCriterion implements Criterion {
-
         private final Short signalType;
         private final Type type;
 
+        /**
+         * Constructor.
+         *
+         * @param signalType the optical signal type to match
+         * @param type the match type. Should be Type.OCH_SIGTYPE
+         */
         public OpticalSignalTypeCriterion(Short signalType, Type type) {
             this.signalType = signalType;
             this.type = type;
@@ -810,6 +1408,11 @@
             return this.type;
         }
 
+        /**
+         * Gets the optical signal type to match.
+         *
+         * @return the optical signal type to match
+         */
         public Short signalType() {
             return this.signalType;
         }
@@ -838,5 +1441,4 @@
             return false;
         }
     }
-
 }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
index 5ce86a7..6122567 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
@@ -24,7 +24,7 @@
     /**
      * Types of fields to which the selection criterion may apply.
      */
-    // From page 42 of OpenFlow 1.3.x spec
+    // From page 75 of OpenFlow 1.5.0 spec
     public enum Type {
         /** Switch input port. */
         IN_PORT,
@@ -106,6 +106,21 @@
         TUNNEL_ID,
         /** IPv6 Extension Header pseudo-field. */
         IPV6_EXTHDR,
+        /** Unassigned value: 40. */
+        UNASSIGNED_40,
+        /** PBB UCA header field. */
+        PBB_UCA,
+        /** TCP flags. */
+        TCP_FLAGS,
+        /** Output port from action set metadata. */
+        ACTSET_OUTPUT,
+        /** Packet type value. */
+        PACKET_TYPE,
+
+        //
+        // NOTE: Everything below is defined elsewhere: ONOS-specific,
+        // extensions, etc.
+        //
         /** Optical channel signal ID (lambda). */
         OCH_SIGID,
         /** Optical channel signal type (fixed or flexible). */
diff --git a/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficSelectorTest.java b/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficSelectorTest.java
index 651773f..e232647 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficSelectorTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficSelectorTest.java
@@ -25,6 +25,7 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onlab.packet.Ip6Address;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
@@ -126,22 +127,25 @@
     public void testCriteriaCreation() {
         TrafficSelector selector;
 
+        final int intValue = 22;
         final short shortValue = 33;
         final byte byteValue = 44;
+        final MacAddress macValue = MacAddress.valueOf("11:22:33:44:55:66");
         final IpPrefix ipPrefixValue = IpPrefix.valueOf("192.168.1.0/24");
         final IpPrefix ipv6PrefixValue = IpPrefix.valueOf("fe80::1/64");
+        final Ip6Address ipv6AddressValue = Ip6Address.valueOf("fe80::1");
 
         selector = DefaultTrafficSelector.builder()
-                .matchInport(PortNumber.portNumber(11)).build();
+                .matchInPort(PortNumber.portNumber(11)).build();
         assertThat(selector, hasCriterionWithType(Type.IN_PORT));
 
         selector = DefaultTrafficSelector.builder()
-                .matchEthSrc(MacAddress.BROADCAST).build();
-        assertThat(selector, hasCriterionWithType(Type.ETH_SRC));
+                .matchEthDst(macValue).build();
+        assertThat(selector, hasCriterionWithType(Type.ETH_DST));
 
         selector = DefaultTrafficSelector.builder()
-                .matchEthDst(MacAddress.BROADCAST).build();
-        assertThat(selector, hasCriterionWithType(Type.ETH_DST));
+                .matchEthSrc(macValue).build();
+        assertThat(selector, hasCriterionWithType(Type.ETH_SRC));
 
         selector = DefaultTrafficSelector.builder()
                 .matchEthType(shortValue).build();
@@ -176,6 +180,30 @@
         assertThat(selector, hasCriterionWithType(Type.TCP_DST));
 
         selector = DefaultTrafficSelector.builder()
+                .matchUdpSrc(shortValue).build();
+        assertThat(selector, hasCriterionWithType(Type.UDP_SRC));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchUdpDst(shortValue).build();
+        assertThat(selector, hasCriterionWithType(Type.UDP_DST));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchSctpSrc(shortValue).build();
+        assertThat(selector, hasCriterionWithType(Type.SCTP_SRC));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchSctpDst(shortValue).build();
+        assertThat(selector, hasCriterionWithType(Type.SCTP_DST));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchIcmpType(byteValue).build();
+        assertThat(selector, hasCriterionWithType(Type.ICMPV4_TYPE));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchIcmpCode(byteValue).build();
+        assertThat(selector, hasCriterionWithType(Type.ICMPV4_CODE));
+
+        selector = DefaultTrafficSelector.builder()
                 .matchIPv6Src(ipv6PrefixValue).build();
         assertThat(selector, hasCriterionWithType(Type.IPV6_SRC));
 
@@ -184,6 +212,26 @@
         assertThat(selector, hasCriterionWithType(Type.IPV6_DST));
 
         selector = DefaultTrafficSelector.builder()
+                .matchIPv6FlowLabel(intValue).build();
+        assertThat(selector, hasCriterionWithType(Type.IPV6_FLABEL));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchIcmpv6Type(byteValue).build();
+        assertThat(selector, hasCriterionWithType(Type.ICMPV6_TYPE));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchIPv6NDTargetAddress(ipv6AddressValue).build();
+        assertThat(selector, hasCriterionWithType(Type.IPV6_ND_TARGET));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchIPv6NDSourceLinkLayerAddress(macValue).build();
+        assertThat(selector, hasCriterionWithType(Type.IPV6_ND_SLL));
+
+        selector = DefaultTrafficSelector.builder()
+                .matchIPv6NDTargetLinkLayerAddress(macValue).build();
+        assertThat(selector, hasCriterionWithType(Type.IPV6_ND_TLL));
+
+        selector = DefaultTrafficSelector.builder()
                 .matchMplsLabel(3).build();
         assertThat(selector, hasCriterionWithType(Type.MPLS_LABEL));
 
@@ -194,12 +242,21 @@
         selector = DefaultTrafficSelector.builder()
                 .matchOpticalSignalType(shortValue).build();
         assertThat(selector, hasCriterionWithType(Type.OCH_SIGTYPE));
+    }
+
+    /**
+     * Tests the traffic selector builder.
+     */
+    @Test
+    public void testTrafficSelectorBuilder() {
+        TrafficSelector selector;
+        final short shortValue = 33;
 
         final TrafficSelector baseSelector = DefaultTrafficSelector.builder()
-                .matchOpticalSignalType(shortValue).build();
+                .matchLambda(shortValue).build();
         selector = DefaultTrafficSelector.builder(baseSelector)
                 .build();
-        assertThat(selector, hasCriterionWithType(Type.OCH_SIGTYPE));
+        assertThat(selector, hasCriterionWithType(Type.OCH_SIGID));
 
         final Criterion criterion = Criteria.matchLambda(shortValue);
         selector = DefaultTrafficSelector.builder()
diff --git a/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java b/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
index a11b227..3cebd8e 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
@@ -18,6 +18,7 @@
 import org.junit.Test;
 import org.onosproject.net.PortNumber;
 import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip6Address;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 
@@ -44,14 +45,10 @@
     Criterion sameAsMatchInPort1 = Criteria.matchInPort(port1);
     Criterion matchInPort2 = Criteria.matchInPort(port2);
 
-    Criterion matchTcpPort1 = Criteria.matchTcpSrc((short) 1);
-    Criterion sameAsMatchTcpPort1 = Criteria.matchTcpSrc((short) 1);
-    Criterion matchTcpPort2 = Criteria.matchTcpDst((short) 2);
-
     private static final String MAC1 = "00:00:00:00:00:01";
     private static final String MAC2 = "00:00:00:00:00:02";
-    private MacAddress mac1 = new MacAddress(MAC1.getBytes());
-    private MacAddress mac2 = new MacAddress(MAC2.getBytes());
+    private MacAddress mac1 = MacAddress.valueOf(MAC1);
+    private MacAddress mac2 = MacAddress.valueOf(MAC2);
     Criterion matchEth1 = Criteria.matchEthSrc(mac1);
     Criterion sameAsMatchEth1 = Criteria.matchEthSrc(mac1);
     Criterion matchEth2 = Criteria.matchEthDst(mac2);
@@ -97,6 +94,82 @@
     Criterion sameAsMatchIpv61 = Criteria.matchIPSrc(ipv61);
     Criterion matchIpv62 = Criteria.matchIPSrc(ipv62);
 
+    Criterion matchTcpPort1 = Criteria.matchTcpSrc((short) 1);
+    Criterion sameAsMatchTcpPort1 = Criteria.matchTcpSrc((short) 1);
+    Criterion matchTcpPort2 = Criteria.matchTcpDst((short) 2);
+
+    Criterion matchUdpPort1 = Criteria.matchUdpSrc((short) 1);
+    Criterion sameAsMatchUdpPort1 = Criteria.matchUdpSrc((short) 1);
+    Criterion matchUdpPort2 = Criteria.matchUdpDst((short) 2);
+
+    Criterion matchSctpPort1 = Criteria.matchSctpSrc((short) 1);
+    Criterion sameAsMatchSctpPort1 = Criteria.matchSctpSrc((short) 1);
+    Criterion matchSctpPort2 = Criteria.matchSctpDst((short) 2);
+
+    byte icmpType1 = 1;
+    byte icmpType2 = 2;
+    Criterion matchIcmpType1 = Criteria.matchIcmpType(icmpType1);
+    Criterion sameAsMatchIcmpType1 = Criteria.matchIcmpType(icmpType1);
+    Criterion matchIcmpType2 = Criteria.matchIcmpType(icmpType2);
+
+    byte icmpCode1 = 1;
+    byte icmpCode2 = 2;
+    Criterion matchIcmpCode1 = Criteria.matchIcmpCode(icmpCode1);
+    Criterion sameAsMatchIcmpCode1 = Criteria.matchIcmpCode(icmpCode1);
+    Criterion matchIcmpCode2 = Criteria.matchIcmpCode(icmpCode2);
+
+    int flowLabel1 = 1;
+    int flowLabel2 = 2;
+    Criterion matchFlowLabel1 = Criteria.matchIPv6FlowLabel(flowLabel1);
+    Criterion sameAsMatchFlowLabel1 = Criteria.matchIPv6FlowLabel(flowLabel1);
+    Criterion matchFlowLabel2 = Criteria.matchIPv6FlowLabel(flowLabel2);
+
+    byte icmpv6Type1 = 1;
+    byte icmpv6Type2 = 2;
+    Criterion matchIcmpv6Type1 = Criteria.matchIcmpv6Type(icmpv6Type1);
+    Criterion sameAsMatchIcmpv6Type1 = Criteria.matchIcmpv6Type(icmpv6Type1);
+    Criterion matchIcmpv6Type2 = Criteria.matchIcmpv6Type(icmpv6Type2);
+
+    byte icmpv6Code1 = 1;
+    byte icmpv6Code2 = 2;
+    Criterion matchIcmpv6Code1 = Criteria.matchIcmpv6Code(icmpv6Code1);
+    Criterion sameAsMatchIcmpv6Code1 = Criteria.matchIcmpv6Code(icmpv6Code1);
+    Criterion matchIcmpv6Code2 = Criteria.matchIcmpv6Code(icmpv6Code2);
+
+    private static final String IPV6_ADDR1 = "fe80::1";
+    private static final String IPV6_ADDR2 = "fe80::2";
+    private Ip6Address ip6TargetAddress1 = Ip6Address.valueOf(IPV6_ADDR1);
+    private Ip6Address ip6TargetAddress2 = Ip6Address.valueOf(IPV6_ADDR2);
+    Criterion matchIpv6TargetAddr1 =
+        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
+    Criterion sameAsMatchIpv6TargetAddr1 =
+        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
+    Criterion matchIpv6TargetAddr2 =
+        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress2);
+
+    private static final String LL_MAC1 = "00:00:00:00:00:01";
+    private static final String LL_MAC2 = "00:00:00:00:00:02";
+    private MacAddress llMac1 = MacAddress.valueOf(LL_MAC1);
+    private MacAddress llMac2 = MacAddress.valueOf(LL_MAC2);
+    Criterion matchSrcLlAddr1 =
+        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
+    Criterion sameAsMatchSrcLlAddr1 =
+        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
+    Criterion matchSrcLlAddr2 =
+        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac2);
+    Criterion matchTargetLlAddr1 =
+        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
+    Criterion sameAsMatchTargetLlAddr1 =
+        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
+    Criterion matchTargetLlAddr2 =
+        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac2);
+
+    int mpls1 = 1;
+    int mpls2 = 2;
+    Criterion matchMpls1 = Criteria.matchMplsLabel(mpls1);
+    Criterion sameAsMatchMpls1 = Criteria.matchMplsLabel(mpls1);
+    Criterion matchMpls2 = Criteria.matchMplsLabel(mpls2);
+
     short lambda1 = 1;
     short lambda2 = 2;
     Criterion matchLambda1 = Criteria.matchLambda(lambda1);
@@ -143,11 +216,21 @@
         assertThatClassIsImmutable(Criteria.PortCriterion.class);
         assertThatClassIsImmutable(Criteria.EthCriterion.class);
         assertThatClassIsImmutable(Criteria.EthTypeCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPProtocolCriterion.class);
-        assertThatClassIsImmutable(Criteria.VlanPcpCriterion.class);
         assertThatClassIsImmutable(Criteria.VlanIdCriterion.class);
+        assertThatClassIsImmutable(Criteria.VlanPcpCriterion.class);
+        assertThatClassIsImmutable(Criteria.IPProtocolCriterion.class);
+        assertThatClassIsImmutable(Criteria.IPCriterion.class);
         assertThatClassIsImmutable(Criteria.TcpPortCriterion.class);
+        assertThatClassIsImmutable(Criteria.UdpPortCriterion.class);
+        assertThatClassIsImmutable(Criteria.SctpPortCriterion.class);
+        assertThatClassIsImmutable(Criteria.IcmpTypeCriterion.class);
+        assertThatClassIsImmutable(Criteria.IcmpCodeCriterion.class);
+        assertThatClassIsImmutable(Criteria.IPv6FlowLabelCriterion.class);
+        assertThatClassIsImmutable(Criteria.Icmpv6TypeCriterion.class);
+        assertThatClassIsImmutable(Criteria.Icmpv6CodeCriterion.class);
+        assertThatClassIsImmutable(Criteria.IPv6NDTargetAddressCriterion.class);
+        assertThatClassIsImmutable(Criteria.IPv6NDLinkLayerAddressCriterion.class);
+        assertThatClassIsImmutable(Criteria.MplsCriterion.class);
         assertThatClassIsImmutable(Criteria.LambdaCriterion.class);
         assertThatClassIsImmutable(Criteria.OpticalSignalTypeCriterion.class);
     }
@@ -182,6 +265,19 @@
     // EthCriterion class
 
     /**
+     * Test the matchEthDst method.
+     */
+    @Test
+    public void testMatchEthDstMethod() {
+        Criterion matchEthDst = Criteria.matchEthDst(mac1);
+        Criteria.EthCriterion ethCriterion =
+                checkAndConvert(matchEthDst,
+                        Criterion.Type.ETH_DST,
+                        Criteria.EthCriterion.class);
+        assertThat(ethCriterion.mac(), is(equalTo(mac1)));
+    }
+
+    /**
      * Test the matchEthSrc method.
      */
     @Test
@@ -195,19 +291,6 @@
     }
 
     /**
-     * Test the matchEthDst method.
-     */
-    @Test
-    public void testMatchEthDstMethod() {
-        Criterion matchTcpDst = Criteria.matchEthDst(mac1);
-        Criteria.EthCriterion ethCriterion =
-                checkAndConvert(matchTcpDst,
-                        Criterion.Type.ETH_DST,
-                        Criteria.EthCriterion.class);
-        assertThat(ethCriterion.mac(), is(equalTo(mac1)));
-    }
-
-    /**
      * Test the equals() method of the EthCriterion class.
      */
     @Test
@@ -218,45 +301,6 @@
                 .testEquals();
     }
 
-    // TcpPortCriterion class
-
-    /**
-     * Test the matchTcpSrc method.
-     */
-    @Test
-    public void testMatchTcpSrcMethod() {
-        Criterion matchTcpSrc = Criteria.matchTcpSrc((short) 1);
-        Criteria.TcpPortCriterion tcpPortCriterion =
-                checkAndConvert(matchTcpSrc,
-                                Criterion.Type.TCP_SRC,
-                                Criteria.TcpPortCriterion.class);
-        assertThat(tcpPortCriterion.tcpPort(), is(equalTo((short) 1)));
-    }
-
-    /**
-     * Test the matchTcpDst method.
-     */
-    @Test
-    public void testMatchTcpDstMethod() {
-        Criterion matchTcpDst = Criteria.matchTcpDst((short) 1);
-        Criteria.TcpPortCriterion tcpPortCriterion =
-                checkAndConvert(matchTcpDst,
-                        Criterion.Type.TCP_DST,
-                        Criteria.TcpPortCriterion.class);
-        assertThat(tcpPortCriterion.tcpPort(), is(equalTo((short) 1)));
-    }
-
-    /**
-     * Test the equals() method of the TcpPortCriterion class.
-     */
-    @Test
-    public void testTcpPortCriterionEquals() {
-        new EqualsTester()
-                .addEqualityGroup(matchTcpPort1, sameAsMatchTcpPort1)
-                .addEqualityGroup(matchTcpPort2)
-                .testEquals();
-    }
-
     // EthTypeCriterion class
 
     /**
@@ -365,7 +409,7 @@
     // IPCriterion class
 
     /**
-     * Test the matchIPSrc method.
+     * Test the matchIPSrc method: IPv4.
      */
     @Test
     public void testMatchIPSrcMethod() {
@@ -378,7 +422,7 @@
     }
 
     /**
-     * Test the matchIPDst method.
+     * Test the matchIPDst method: IPv4.
      */
     @Test
     public void testMatchIPDstMethod() {
@@ -391,7 +435,7 @@
     }
 
     /**
-     * Test the matchIPSrc method.
+     * Test the matchIPSrc method: IPv6.
      */
     @Test
     public void testMatchIPv6SrcMethod() {
@@ -404,7 +448,7 @@
     }
 
     /**
-     * Test the matchIPDst method.
+     * Test the matchIPDst method: IPv6.
      */
     @Test
     public void testMatchIPv6DstMethod() {
@@ -432,6 +476,359 @@
                 .testEquals();
     }
 
+    // TcpPortCriterion class
+
+    /**
+     * Test the matchTcpSrc method.
+     */
+    @Test
+    public void testMatchTcpSrcMethod() {
+        Criterion matchTcpSrc = Criteria.matchTcpSrc((short) 1);
+        Criteria.TcpPortCriterion tcpPortCriterion =
+                checkAndConvert(matchTcpSrc,
+                                Criterion.Type.TCP_SRC,
+                                Criteria.TcpPortCriterion.class);
+        assertThat(tcpPortCriterion.tcpPort(), is(equalTo((short) 1)));
+    }
+
+    /**
+     * Test the matchTcpDst method.
+     */
+    @Test
+    public void testMatchTcpDstMethod() {
+        Criterion matchTcpDst = Criteria.matchTcpDst((short) 1);
+        Criteria.TcpPortCriterion tcpPortCriterion =
+                checkAndConvert(matchTcpDst,
+                        Criterion.Type.TCP_DST,
+                        Criteria.TcpPortCriterion.class);
+        assertThat(tcpPortCriterion.tcpPort(), is(equalTo((short) 1)));
+    }
+
+    /**
+     * Test the equals() method of the TcpPortCriterion class.
+     */
+    @Test
+    public void testTcpPortCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchTcpPort1, sameAsMatchTcpPort1)
+                .addEqualityGroup(matchTcpPort2)
+                .testEquals();
+    }
+
+    // UdpPortCriterion class
+
+    /**
+     * Test the matchUdpSrc method.
+     */
+    @Test
+    public void testMatchUdpSrcMethod() {
+        Criterion matchUdpSrc = Criteria.matchUdpSrc((short) 1);
+        Criteria.UdpPortCriterion udpPortCriterion =
+                checkAndConvert(matchUdpSrc,
+                                Criterion.Type.UDP_SRC,
+                                Criteria.UdpPortCriterion.class);
+        assertThat(udpPortCriterion.udpPort(), is(equalTo((short) 1)));
+    }
+
+    /**
+     * Test the matchUdpDst method.
+     */
+    @Test
+    public void testMatchUdpDstMethod() {
+        Criterion matchUdpDst = Criteria.matchUdpDst((short) 1);
+        Criteria.UdpPortCriterion udpPortCriterion =
+                checkAndConvert(matchUdpDst,
+                        Criterion.Type.UDP_DST,
+                        Criteria.UdpPortCriterion.class);
+        assertThat(udpPortCriterion.udpPort(), is(equalTo((short) 1)));
+    }
+
+    /**
+     * Test the equals() method of the UdpPortCriterion class.
+     */
+    @Test
+    public void testUdpPortCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchUdpPort1, sameAsMatchUdpPort1)
+                .addEqualityGroup(matchUdpPort2)
+                .testEquals();
+    }
+
+    // SctpPortCriterion class
+
+    /**
+     * Test the matchSctpSrc method.
+     */
+    @Test
+    public void testMatchSctpSrcMethod() {
+        Criterion matchSctpSrc = Criteria.matchSctpSrc((short) 1);
+        Criteria.SctpPortCriterion sctpPortCriterion =
+                checkAndConvert(matchSctpSrc,
+                                Criterion.Type.SCTP_SRC,
+                                Criteria.SctpPortCriterion.class);
+        assertThat(sctpPortCriterion.sctpPort(), is(equalTo((short) 1)));
+    }
+
+    /**
+     * Test the matchSctpDst method.
+     */
+    @Test
+    public void testMatchSctpDstMethod() {
+        Criterion matchSctpDst = Criteria.matchSctpDst((short) 1);
+        Criteria.SctpPortCriterion sctpPortCriterion =
+                checkAndConvert(matchSctpDst,
+                        Criterion.Type.SCTP_DST,
+                        Criteria.SctpPortCriterion.class);
+        assertThat(sctpPortCriterion.sctpPort(), is(equalTo((short) 1)));
+    }
+
+    /**
+     * Test the equals() method of the SctpPortCriterion class.
+     */
+    @Test
+    public void testSctpPortCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchSctpPort1, sameAsMatchSctpPort1)
+                .addEqualityGroup(matchSctpPort2)
+                .testEquals();
+    }
+
+    // IcmpTypeCriterion class
+
+    /**
+     * Test the matchIcmpType method.
+     */
+    @Test
+    public void testMatchIcmpTypeMethod() {
+        Byte icmpType = 12;
+        Criterion matchIcmpType = Criteria.matchIcmpType(icmpType);
+        Criteria.IcmpTypeCriterion icmpTypeCriterion =
+                checkAndConvert(matchIcmpType,
+                                Criterion.Type.ICMPV4_TYPE,
+                                Criteria.IcmpTypeCriterion.class);
+        assertThat(icmpTypeCriterion.icmpType(), is(equalTo(icmpType)));
+    }
+
+    /**
+     * Test the equals() method of the IcmpTypeCriterion class.
+     */
+    @Test
+    public void testIcmpTypeCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchIcmpType1, sameAsMatchIcmpType1)
+                .addEqualityGroup(matchIcmpType2)
+                .testEquals();
+    }
+
+    // IcmpCodeCriterion class
+
+    /**
+     * Test the matchIcmpCode method.
+     */
+    @Test
+    public void testMatchIcmpCodeMethod() {
+        Byte icmpCode = 12;
+        Criterion matchIcmpCode = Criteria.matchIcmpCode(icmpCode);
+        Criteria.IcmpCodeCriterion icmpCodeCriterion =
+                checkAndConvert(matchIcmpCode,
+                                Criterion.Type.ICMPV4_CODE,
+                                Criteria.IcmpCodeCriterion.class);
+        assertThat(icmpCodeCriterion.icmpCode(), is(equalTo(icmpCode)));
+    }
+
+    /**
+     * Test the equals() method of the IcmpCodeCriterion class.
+     */
+    @Test
+    public void testIcmpCodeCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchIcmpCode1, sameAsMatchIcmpCode1)
+                .addEqualityGroup(matchIcmpCode2)
+                .testEquals();
+    }
+
+    // IPv6FlowLabelCriterion class
+
+    /**
+     * Test the matchIPv6FlowLabel method.
+     */
+    @Test
+    public void testMatchIPv6FlowLabelMethod() {
+        Integer flowLabel = 12;
+        Criterion matchFlowLabel = Criteria.matchIPv6FlowLabel(flowLabel);
+        Criteria.IPv6FlowLabelCriterion flowLabelCriterion =
+                checkAndConvert(matchFlowLabel,
+                                Criterion.Type.IPV6_FLABEL,
+                                Criteria.IPv6FlowLabelCriterion.class);
+        assertThat(flowLabelCriterion.flowLabel(), is(equalTo(flowLabel)));
+    }
+
+    /**
+     * Test the equals() method of the IPv6FlowLabelCriterion class.
+     */
+    @Test
+    public void testIPv6FlowLabelCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchFlowLabel1, sameAsMatchFlowLabel1)
+                .addEqualityGroup(matchFlowLabel2)
+                .testEquals();
+    }
+
+    // Icmpv6TypeCriterion class
+
+    /**
+     * Test the matchIcmpv6Type method.
+     */
+    @Test
+    public void testMatchIcmpv6TypeMethod() {
+        Byte icmpv6Type = 12;
+        Criterion matchIcmpv6Type = Criteria.matchIcmpv6Type(icmpv6Type);
+        Criteria.Icmpv6TypeCriterion icmpv6TypeCriterion =
+                checkAndConvert(matchIcmpv6Type,
+                                Criterion.Type.ICMPV6_TYPE,
+                                Criteria.Icmpv6TypeCriterion.class);
+        assertThat(icmpv6TypeCriterion.icmpv6Type(), is(equalTo(icmpv6Type)));
+    }
+
+    /**
+     * Test the equals() method of the Icmpv6TypeCriterion class.
+     */
+    @Test
+    public void testIcmpv6TypeCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchIcmpv6Type1, sameAsMatchIcmpv6Type1)
+                .addEqualityGroup(matchIcmpv6Type2)
+                .testEquals();
+    }
+
+    // Icmpv6CodeCriterion class
+
+    /**
+     * Test the matchIcmpv6Code method.
+     */
+    @Test
+    public void testMatchIcmpv6CodeMethod() {
+        Byte icmpv6Code = 12;
+        Criterion matchIcmpv6Code = Criteria.matchIcmpv6Code(icmpv6Code);
+        Criteria.Icmpv6CodeCriterion icmpv6CodeCriterion =
+                checkAndConvert(matchIcmpv6Code,
+                                Criterion.Type.ICMPV6_CODE,
+                                Criteria.Icmpv6CodeCriterion.class);
+        assertThat(icmpv6CodeCriterion.icmpv6Code(), is(equalTo(icmpv6Code)));
+    }
+
+    /**
+     * Test the equals() method of the Icmpv6CodeCriterion class.
+     */
+    @Test
+    public void testIcmpv6CodeCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchIcmpv6Code1, sameAsMatchIcmpv6Code1)
+                .addEqualityGroup(matchIcmpv6Code2)
+                .testEquals();
+    }
+
+    // IPv6NDTargetAddressCriterion class
+
+    /**
+     * Test the matchIPv6NDTargetAddress method.
+     */
+    @Test
+    public void testMatchIPv6NDTargetAddressMethod() {
+        Criterion matchTargetAddress =
+            Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
+        Criteria.IPv6NDTargetAddressCriterion targetAddressCriterion =
+                checkAndConvert(matchTargetAddress,
+                                Criterion.Type.IPV6_ND_TARGET,
+                                Criteria.IPv6NDTargetAddressCriterion.class);
+        assertThat(targetAddressCriterion.targetAddress(),
+                   is(ip6TargetAddress1));
+    }
+
+    /**
+     * Test the equals() method of the IPv6NDTargetAddressCriterion class.
+     */
+    @Test
+    public void testIPv6NDTargetAddressCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchIpv6TargetAddr1,
+                                  sameAsMatchIpv6TargetAddr1)
+                .addEqualityGroup(matchIpv6TargetAddr2)
+                .testEquals();
+    }
+
+    // IPv6NDLinkLayerAddressCriterion class
+
+    /**
+     * Test the matchIPv6NDSourceLinkLayerAddress method.
+     */
+    @Test
+    public void testMatchIPv6NDSourceLinkLayerAddressMethod() {
+        Criterion matchSrcLlAddr =
+            Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
+        Criteria.IPv6NDLinkLayerAddressCriterion srcLlCriterion =
+                checkAndConvert(matchSrcLlAddr,
+                        Criterion.Type.IPV6_ND_SLL,
+                        Criteria.IPv6NDLinkLayerAddressCriterion.class);
+        assertThat(srcLlCriterion.mac(), is(equalTo(llMac1)));
+    }
+
+    /**
+     * Test the matchIPv6NDTargetLinkLayerAddress method.
+     */
+    @Test
+    public void testMatchIPv6NDTargetLinkLayerAddressMethod() {
+        Criterion matchTargetLlAddr =
+            Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
+        Criteria.IPv6NDLinkLayerAddressCriterion targetLlCriterion =
+                checkAndConvert(matchTargetLlAddr,
+                        Criterion.Type.IPV6_ND_TLL,
+                        Criteria.IPv6NDLinkLayerAddressCriterion.class);
+        assertThat(targetLlCriterion.mac(), is(equalTo(llMac1)));
+    }
+
+    /**
+     * Test the equals() method of the IPv6NDLinkLayerAddressCriterion class.
+     */
+    @Test
+    public void testIPv6NDLinkLayerAddressCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchSrcLlAddr1, sameAsMatchSrcLlAddr1)
+                .addEqualityGroup(matchSrcLlAddr2)
+                .testEquals();
+
+        new EqualsTester()
+                .addEqualityGroup(matchTargetLlAddr1, sameAsMatchTargetLlAddr1)
+                .addEqualityGroup(matchTargetLlAddr2)
+                .testEquals();
+    }
+
+    // MplsCriterion class
+
+    /**
+     * Test the matchMplsLabel method.
+     */
+    @Test
+    public void testMatchMplsLabelMethod() {
+        Criterion matchMplsLabel = Criteria.matchMplsLabel(mpls1);
+        Criteria.MplsCriterion mplsCriterion =
+                checkAndConvert(matchMplsLabel,
+                        Criterion.Type.MPLS_LABEL,
+                        Criteria.MplsCriterion.class);
+        assertThat(mplsCriterion.label(), is(equalTo(mpls1)));
+    }
+
+    /**
+     * Test the equals() method of the MplsCriterion class.
+     */
+    @Test
+    public void testMplsCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchMpls1, sameAsMatchMpls1)
+                .addEqualityGroup(matchMpls2)
+                .testEquals();
+    }
+
     // LambdaCriterion class
 
     /**
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/OpticalPathIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/OpticalPathIntentInstaller.java
index 4be9bf5..e958c58 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/OpticalPathIntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/OpticalPathIntentInstaller.java
@@ -127,7 +127,7 @@
                                                        LinkResourceAllocations allocations,
                                                        FlowRuleOperation operation) {
         TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
-        selectorBuilder.matchInport(intent.src().port());
+        selectorBuilder.matchInPort(intent.src().port());
 
         List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
         ConnectPoint prev = intent.src();
@@ -163,7 +163,7 @@
             rules.add(new FlowRuleBatchEntry(operation, rule));
 
             prev = link.dst();
-            selectorBuilder.matchInport(link.dst().port());
+            selectorBuilder.matchInPort(link.dst().port());
             selectorBuilder.matchOpticalSignalType(SIGNAL_TYPE); //todo
             selectorBuilder.matchLambda((short) la.toInt());
 
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/PathIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/PathIntentInstaller.java
index 64c2b8e..1c8ea7e 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/PathIntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/PathIntentInstaller.java
@@ -92,7 +92,7 @@
         List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
         // TODO Generate multiple batches
         while (links.hasNext()) {
-            builder.matchInport(prev.port());
+            builder.matchInPort(prev.port());
             Link link = links.next();
             // if this is the last flow rule, apply the intent's treatments
             TrafficTreatment treatment =
@@ -124,7 +124,7 @@
         List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
         // TODO Generate multiple batches
         while (links.hasNext()) {
-            builder.matchInport(prev.port());
+            builder.matchInPort(prev.port());
             Link link = links.next();
             // if this is the last flow rule, apply the intent's treatments
             TrafficTreatment treatment =
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 3c1e643..5b0e1ef 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
@@ -18,6 +18,7 @@
 import com.google.common.collect.Lists;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.Ip6Address;
 import org.onlab.packet.Ip6Prefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
@@ -348,65 +349,30 @@
     }
 
     private TrafficSelector buildSelector() {
+        MacAddress mac;
+        Ip4Prefix ip4Prefix;
+        Ip6Address ip6Address;
+        Ip6Prefix ip6Prefix;
+
         TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
         for (MatchField<?> field : match.getMatchFields()) {
             switch (field.id) {
             case IN_PORT:
-                builder.matchInport(PortNumber
+                builder.matchInPort(PortNumber
                         .portNumber(match.get(MatchField.IN_PORT).getPortNumber()));
                 break;
-            case ETH_SRC:
-                MacAddress sMac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
-                builder.matchEthSrc(sMac);
-                break;
             case ETH_DST:
-                MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
-                builder.matchEthDst(dMac);
+                mac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
+                builder.matchEthDst(mac);
+                break;
+            case ETH_SRC:
+                mac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
+                builder.matchEthSrc(mac);
                 break;
             case ETH_TYPE:
                 int ethType = match.get(MatchField.ETH_TYPE).getValue();
                 builder.matchEthType((short) ethType);
                 break;
-            case IPV4_DST:
-                Ip4Prefix dip;
-                if (match.isPartiallyMasked(MatchField.IPV4_DST)) {
-                    Masked<IPv4Address> maskedIp = match.getMasked(MatchField.IPV4_DST);
-
-                    dip = Ip4Prefix.valueOf(
-                            maskedIp.getValue().getInt(),
-                            maskedIp.getMask().asCidrMaskLength());
-                } else {
-                    dip = Ip4Prefix.valueOf(
-                            match.get(MatchField.IPV4_DST).getInt(),
-                            Ip4Prefix.MAX_MASK_LENGTH);
-                }
-
-                builder.matchIPDst(dip);
-                break;
-            case IPV4_SRC:
-                Ip4Prefix sip;
-                if (match.isPartiallyMasked(MatchField.IPV4_SRC)) {
-                    Masked<IPv4Address> maskedIp = match.getMasked(MatchField.IPV4_SRC);
-
-                    sip = Ip4Prefix.valueOf(
-                            maskedIp.getValue().getInt(),
-                            maskedIp.getMask().asCidrMaskLength());
-                } else {
-                    sip = Ip4Prefix.valueOf(
-                            match.get(MatchField.IPV4_SRC).getInt(),
-                            Ip4Prefix.MAX_MASK_LENGTH);
-                }
-
-                builder.matchIPSrc(sip);
-                break;
-            case IP_PROTO:
-                short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
-                builder.matchIPProtocol((byte) proto);
-                break;
-            case VLAN_PCP:
-                byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
-                builder.matchVlanPcp(vlanPcp);
-                break;
             case VLAN_VID:
                 VlanId vlanId = null;
                 if (match.isPartiallyMasked(MatchField.VLAN_VID)) {
@@ -422,12 +388,122 @@
                     builder.matchVlanId(vlanId);
                 }
                 break;
-            case TCP_DST:
-                builder.matchTcpDst((short) match.get(MatchField.TCP_DST).getPort());
+            case VLAN_PCP:
+                byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
+                builder.matchVlanPcp(vlanPcp);
+                break;
+            case IP_PROTO:
+                short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
+                builder.matchIPProtocol((byte) proto);
+                break;
+            case IPV4_SRC:
+                if (match.isPartiallyMasked(MatchField.IPV4_SRC)) {
+                    Masked<IPv4Address> maskedIp = match.getMasked(MatchField.IPV4_SRC);
+
+                    ip4Prefix = Ip4Prefix.valueOf(
+                            maskedIp.getValue().getInt(),
+                            maskedIp.getMask().asCidrMaskLength());
+                } else {
+                    ip4Prefix = Ip4Prefix.valueOf(
+                            match.get(MatchField.IPV4_SRC).getInt(),
+                            Ip4Prefix.MAX_MASK_LENGTH);
+                }
+
+                builder.matchIPSrc(ip4Prefix);
+                break;
+            case IPV4_DST:
+                if (match.isPartiallyMasked(MatchField.IPV4_DST)) {
+                    Masked<IPv4Address> maskedIp = match.getMasked(MatchField.IPV4_DST);
+
+                    ip4Prefix = Ip4Prefix.valueOf(
+                            maskedIp.getValue().getInt(),
+                            maskedIp.getMask().asCidrMaskLength());
+                } else {
+                    ip4Prefix = Ip4Prefix.valueOf(
+                            match.get(MatchField.IPV4_DST).getInt(),
+                            Ip4Prefix.MAX_MASK_LENGTH);
+                }
+
+                builder.matchIPDst(ip4Prefix);
                 break;
             case TCP_SRC:
                 builder.matchTcpSrc((short) match.get(MatchField.TCP_SRC).getPort());
                 break;
+            case TCP_DST:
+                builder.matchTcpDst((short) match.get(MatchField.TCP_DST).getPort());
+                break;
+            case UDP_SRC:
+                builder.matchUdpSrc((short) match.get(MatchField.UDP_SRC).getPort());
+                break;
+            case UDP_DST:
+                builder.matchUdpDst((short) match.get(MatchField.UDP_DST).getPort());
+                break;
+            case SCTP_SRC:
+                builder.matchSctpSrc((short) match.get(MatchField.SCTP_SRC).getPort());
+                break;
+            case SCTP_DST:
+                builder.matchSctpDst((short) match.get(MatchField.SCTP_DST).getPort());
+                break;
+            case ICMPV4_TYPE:
+                byte icmpType = (byte) match.get(MatchField.ICMPV4_TYPE).getType();
+                builder.matchIcmpType(icmpType);
+                break;
+            case ICMPV4_CODE:
+                byte icmpCode = (byte) match.get(MatchField.ICMPV4_CODE).getCode();
+                builder.matchIcmpCode(icmpCode);
+                break;
+            case IPV6_SRC:
+                if (match.isPartiallyMasked(MatchField.IPV6_SRC)) {
+                    Masked<IPv6Address> maskedIp = match.getMasked(MatchField.IPV6_SRC);
+                    ip6Prefix = Ip6Prefix.valueOf(
+                            maskedIp.getValue().getBytes(),
+                            maskedIp.getMask().asCidrMaskLength());
+                } else {
+                    ip6Prefix = Ip6Prefix.valueOf(
+                            match.get(MatchField.IPV6_SRC).getBytes(),
+                            Ip6Prefix.MAX_MASK_LENGTH);
+                }
+                builder.matchIPv6Src(ip6Prefix);
+                break;
+            case IPV6_DST:
+                if (match.isPartiallyMasked(MatchField.IPV6_DST)) {
+                    Masked<IPv6Address> maskedIp = match.getMasked(MatchField.IPV6_DST);
+                    ip6Prefix = Ip6Prefix.valueOf(
+                            maskedIp.getValue().getBytes(),
+                            maskedIp.getMask().asCidrMaskLength());
+                } else {
+                    ip6Prefix = Ip6Prefix.valueOf(
+                            match.get(MatchField.IPV6_DST).getBytes(),
+                            Ip6Prefix.MAX_MASK_LENGTH);
+                }
+                builder.matchIPv6Dst(ip6Prefix);
+                break;
+            case IPV6_FLABEL:
+                int flowLabel =
+                    match.get(MatchField.IPV6_FLABEL).getIPv6FlowLabelValue();
+                builder.matchIPv6FlowLabel(flowLabel);
+                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 IPV6_ND_TARGET:
+                ip6Address =
+                    Ip6Address.valueOf(match.get(MatchField.IPV6_ND_TARGET).getBytes());
+                builder.matchIPv6NDTargetAddress(ip6Address);
+                break;
+            case IPV6_ND_SLL:
+                mac = MacAddress.valueOf(match.get(MatchField.IPV6_ND_SLL).getLong());
+                builder.matchIPv6NDSourceLinkLayerAddress(mac);
+                break;
+            case IPV6_ND_TLL:
+                mac = MacAddress.valueOf(match.get(MatchField.IPV6_ND_TLL).getLong());
+                builder.matchIPv6NDTargetLinkLayerAddress(mac);
+                break;
             case MPLS_LABEL:
                 builder.matchMplsLabel((int) match.get(MatchField.MPLS_LABEL)
                                             .getValue());
@@ -439,63 +515,17 @@
                 builder.matchOpticalSignalType(match.get(MatchField
                                                                  .OCH_SIGTYPE).getValue());
                 break;
-            case IPV6_DST:
-                Ip6Prefix dipv6;
-                if (match.isPartiallyMasked(MatchField.IPV6_DST)) {
-                    Masked<IPv6Address> maskedIp = match.getMasked(MatchField.IPV6_DST);
-                    dipv6 = Ip6Prefix.valueOf(
-                            maskedIp.getValue().getBytes(),
-                            maskedIp.getMask().asCidrMaskLength());
-                } else {
-                    dipv6 = Ip6Prefix.valueOf(
-                            match.get(MatchField.IPV6_DST).getBytes(),
-                            Ip6Prefix.MAX_MASK_LENGTH);
-                }
-                builder.matchIPv6Dst(dipv6);
-                break;
-            case IPV6_SRC:
-                Ip6Prefix sipv6;
-                if (match.isPartiallyMasked(MatchField.IPV6_SRC)) {
-                    Masked<IPv6Address> maskedIp = match.getMasked(MatchField.IPV6_SRC);
-                    sipv6 = Ip6Prefix.valueOf(
-                            maskedIp.getValue().getBytes(),
-                            maskedIp.getMask().asCidrMaskLength());
-                } else {
-                    sipv6 = Ip6Prefix.valueOf(
-                            match.get(MatchField.IPV6_SRC).getBytes(),
-                            Ip6Prefix.MAX_MASK_LENGTH);
-                }
-                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:
             case ARP_THA:
             case ARP_TPA:
-            case ICMPV4_CODE:
-            case ICMPV4_TYPE:
             case IN_PHY_PORT:
-            case IPV6_FLABEL:
-            case IPV6_ND_SLL:
-            case IPV6_ND_TARGET:
-            case IPV6_ND_TLL:
             case IP_DSCP:
             case IP_ECN:
             case METADATA:
             case MPLS_TC:
-            case SCTP_DST:
-            case SCTP_SRC:
             case TUNNEL_ID:
-            case UDP_DST:
-            case UDP_SRC:
             default:
                 log.warn("Match type {} not yet implemented.", field.id);
             }
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 016b0cf..dc954da 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
@@ -25,13 +25,20 @@
 import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criteria.EthCriterion;
 import org.onosproject.net.flow.criteria.Criteria.EthTypeCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.Criteria.IcmpCodeCriterion;
+import org.onosproject.net.flow.criteria.Criteria.IcmpTypeCriterion;
 import org.onosproject.net.flow.criteria.Criteria.Icmpv6CodeCriterion;
 import org.onosproject.net.flow.criteria.Criteria.Icmpv6TypeCriterion;
+import org.onosproject.net.flow.criteria.Criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.Criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.Criteria.IPv6FlowLabelCriterion;
+import org.onosproject.net.flow.criteria.Criteria.IPv6NDLinkLayerAddressCriterion;
+import org.onosproject.net.flow.criteria.Criteria.IPv6NDTargetAddressCriterion;
 import org.onosproject.net.flow.criteria.Criteria.LambdaCriterion;
 import org.onosproject.net.flow.criteria.Criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.Criteria.SctpPortCriterion;
 import org.onosproject.net.flow.criteria.Criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.Criteria.UdpPortCriterion;
 import org.onosproject.net.flow.criteria.Criteria.VlanIdCriterion;
 import org.onosproject.net.flow.criteria.Criteria.VlanPcpCriterion;
 import org.onosproject.net.flow.criteria.Criterion;
@@ -43,8 +50,11 @@
 import org.projectfloodlight.openflow.protocol.match.MatchField;
 import org.projectfloodlight.openflow.types.CircuitSignalID;
 import org.projectfloodlight.openflow.types.EthType;
+import org.projectfloodlight.openflow.types.ICMPv4Code;
+import org.projectfloodlight.openflow.types.ICMPv4Type;
 import org.projectfloodlight.openflow.types.IPv4Address;
 import org.projectfloodlight.openflow.types.IPv6Address;
+import org.projectfloodlight.openflow.types.IPv6FlowLabel;
 import org.projectfloodlight.openflow.types.IpProtocol;
 import org.projectfloodlight.openflow.types.MacAddress;
 import org.projectfloodlight.openflow.types.Masked;
@@ -135,69 +145,39 @@
      *
      * @return the match
      */
+    // CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES
     protected Match buildMatch() {
         Match.Builder mBuilder = factory.buildMatch();
-        EthCriterion eth;
-        IPCriterion ip;
+        Ip6Address ip6Address;
         Ip4Prefix ip4Prefix;
         Ip6Prefix ip6Prefix;
-        TcpPortCriterion tp;
+        EthCriterion ethCriterion;
+        IPCriterion ipCriterion;
+        TcpPortCriterion tcpPortCriterion;
+        UdpPortCriterion udpPortCriterion;
+        SctpPortCriterion sctpPortCriterion;
+        IPv6NDLinkLayerAddressCriterion llAddressCriterion;
+
         for (Criterion c : selector.criteria()) {
             switch (c.type()) {
             case IN_PORT:
                 PortCriterion inport = (PortCriterion) c;
                 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
                 break;
-            case ETH_SRC:
-                eth = (EthCriterion) c;
-                mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
-                break;
             case ETH_DST:
-                eth = (EthCriterion) c;
-                mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
+                ethCriterion = (EthCriterion) c;
+                mBuilder.setExact(MatchField.ETH_DST,
+                                  MacAddress.of(ethCriterion.mac().toLong()));
+                break;
+            case ETH_SRC:
+                ethCriterion = (EthCriterion) c;
+                mBuilder.setExact(MatchField.ETH_SRC,
+                                  MacAddress.of(ethCriterion.mac().toLong()));
                 break;
             case ETH_TYPE:
                 EthTypeCriterion ethType = (EthTypeCriterion) c;
                 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
                 break;
-            case IPV4_DST:
-                ip = (IPCriterion) c;
-                ip4Prefix = ip.ip().getIp4Prefix();
-                if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
-                    Ip4Address maskAddr =
-                        Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
-                    Masked<IPv4Address> maskedIp =
-                        Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
-                                  IPv4Address.of(maskAddr.toInt()));
-                    mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
-                } else {
-                    mBuilder.setExact(MatchField.IPV4_DST,
-                                IPv4Address.of(ip4Prefix.address().toInt()));
-                }
-                break;
-            case IPV4_SRC:
-                ip = (IPCriterion) c;
-                ip4Prefix = ip.ip().getIp4Prefix();
-                if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
-                    Ip4Address maskAddr =
-                        Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
-                    Masked<IPv4Address> maskedIp =
-                        Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
-                                  IPv4Address.of(maskAddr.toInt()));
-                    mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
-                } else {
-                    mBuilder.setExact(MatchField.IPV4_SRC,
-                                IPv4Address.of(ip4Prefix.address().toInt()));
-                }
-                break;
-            case IP_PROTO:
-                IPProtocolCriterion p = (IPProtocolCriterion) c;
-                mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
-                break;
-            case VLAN_PCP:
-                VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
-                mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
-                break;
             case VLAN_VID:
                 VlanIdCriterion vid = (VlanIdCriterion) c;
 
@@ -209,13 +189,148 @@
                             OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
                 }
                 break;
-            case TCP_DST:
-                tp = (TcpPortCriterion) c;
-                mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
+            case VLAN_PCP:
+                VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
+                mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
+                break;
+            case IP_PROTO:
+                IPProtocolCriterion p = (IPProtocolCriterion) c;
+                mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
+                break;
+            case IPV4_SRC:
+                ipCriterion = (IPCriterion) c;
+                ip4Prefix = ipCriterion.ip().getIp4Prefix();
+                if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
+                    Ip4Address maskAddr =
+                        Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
+                    Masked<IPv4Address> maskedIp =
+                        Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
+                                  IPv4Address.of(maskAddr.toInt()));
+                    mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
+                } else {
+                    mBuilder.setExact(MatchField.IPV4_SRC,
+                                IPv4Address.of(ip4Prefix.address().toInt()));
+                }
+                break;
+            case IPV4_DST:
+                ipCriterion = (IPCriterion) c;
+                ip4Prefix = ipCriterion.ip().getIp4Prefix();
+                if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
+                    Ip4Address maskAddr =
+                        Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
+                    Masked<IPv4Address> maskedIp =
+                        Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
+                                  IPv4Address.of(maskAddr.toInt()));
+                    mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
+                } else {
+                    mBuilder.setExact(MatchField.IPV4_DST,
+                                IPv4Address.of(ip4Prefix.address().toInt()));
+                }
                 break;
             case TCP_SRC:
-                tp = (TcpPortCriterion) c;
-                mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
+                tcpPortCriterion = (TcpPortCriterion) c;
+                mBuilder.setExact(MatchField.TCP_SRC,
+                                  TransportPort.of(tcpPortCriterion.tcpPort()));
+                break;
+            case TCP_DST:
+                tcpPortCriterion = (TcpPortCriterion) c;
+                mBuilder.setExact(MatchField.TCP_DST,
+                                  TransportPort.of(tcpPortCriterion.tcpPort()));
+                break;
+            case UDP_SRC:
+                udpPortCriterion = (UdpPortCriterion) c;
+                mBuilder.setExact(MatchField.UDP_SRC,
+                                  TransportPort.of(udpPortCriterion.udpPort()));
+                break;
+            case UDP_DST:
+                udpPortCriterion = (UdpPortCriterion) c;
+                mBuilder.setExact(MatchField.UDP_DST,
+                                  TransportPort.of(udpPortCriterion.udpPort()));
+                break;
+            case SCTP_SRC:
+                sctpPortCriterion = (SctpPortCriterion) c;
+                mBuilder.setExact(MatchField.SCTP_SRC,
+                                  TransportPort.of(sctpPortCriterion.sctpPort()));
+                break;
+            case SCTP_DST:
+                sctpPortCriterion = (SctpPortCriterion) c;
+                mBuilder.setExact(MatchField.SCTP_DST,
+                                  TransportPort.of(sctpPortCriterion.sctpPort()));
+                break;
+            case ICMPV4_TYPE:
+                IcmpTypeCriterion icmpType = (IcmpTypeCriterion) c;
+                mBuilder.setExact(MatchField.ICMPV4_TYPE,
+                                  ICMPv4Type.of(icmpType.icmpType()));
+                break;
+            case ICMPV4_CODE:
+                IcmpCodeCriterion icmpCode = (IcmpCodeCriterion) c;
+                mBuilder.setExact(MatchField.ICMPV4_CODE,
+                                  ICMPv4Code.of(icmpCode.icmpCode()));
+                break;
+            case IPV6_SRC:
+                ipCriterion = (IPCriterion) c;
+                ip6Prefix = ipCriterion.ip().getIp6Prefix();
+                if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
+                    Ip6Address maskAddr =
+                            Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
+                    Masked<IPv6Address> maskedIp =
+                            Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
+                                    IPv6Address.of(maskAddr.toString()));
+                    mBuilder.setMasked(MatchField.IPV6_SRC, maskedIp);
+                } else {
+                    mBuilder.setExact(MatchField.IPV6_SRC,
+                            IPv6Address.of(ip6Prefix.address().toString()));
+                }
+                break;
+            case IPV6_DST:
+                ipCriterion = (IPCriterion) c;
+                ip6Prefix = ipCriterion.ip().getIp6Prefix();
+                if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
+                    Ip6Address maskAddr =
+                            Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
+                    Masked<IPv6Address> maskedIp =
+                            Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
+                                    IPv6Address.of(maskAddr.toString()));
+                    mBuilder.setMasked(MatchField.IPV6_DST, maskedIp);
+                } else {
+                    mBuilder.setExact(MatchField.IPV6_DST,
+                            IPv6Address.of(ip6Prefix.address().toString()));
+                }
+                break;
+            case IPV6_FLABEL:
+                IPv6FlowLabelCriterion flowLabelCriterion =
+                    (IPv6FlowLabelCriterion) c;
+                mBuilder.setExact(MatchField.IPV6_FLABEL,
+                                  IPv6FlowLabel.of(flowLabelCriterion.flowLabel()));
+                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 IPV6_ND_TARGET:
+                IPv6NDTargetAddressCriterion targetAddressCriterion =
+                    (IPv6NDTargetAddressCriterion) c;
+                ip6Address = targetAddressCriterion.targetAddress();
+                mBuilder.setExact(MatchField.IPV6_ND_TARGET,
+                                  IPv6Address.of(ip6Address.toOctets()));
+                break;
+            case IPV6_ND_SLL:
+                llAddressCriterion =
+                    (IPv6NDLinkLayerAddressCriterion) c;
+                mBuilder.setExact(MatchField.IPV6_ND_SLL,
+                        MacAddress.of(llAddressCriterion.mac().toLong()));
+                break;
+            case IPV6_ND_TLL:
+                llAddressCriterion =
+                    (IPv6NDLinkLayerAddressCriterion) c;
+                mBuilder.setExact(MatchField.IPV6_ND_TLL,
+                        MacAddress.of(llAddressCriterion.mac().toLong()));
                 break;
             case MPLS_LABEL:
                 Criteria.MplsCriterion mp = (Criteria.MplsCriterion) c;
@@ -233,70 +348,20 @@
                 mBuilder.setExact(MatchField.OCH_SIGTYPE,
                                   U8.of(sc.signalType()));
                 break;
-            case IPV6_DST:
-                ip = (IPCriterion) c;
-                ip6Prefix = ip.ip().getIp6Prefix();
-                if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
-                    Ip6Address maskAddr =
-                            Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
-                    Masked<IPv6Address> maskedIp =
-                            Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
-                                    IPv6Address.of(maskAddr.toString()));
-                    mBuilder.setMasked(MatchField.IPV6_DST, maskedIp);
-                } else {
-                    mBuilder.setExact(MatchField.IPV6_DST,
-                            IPv6Address.of(ip6Prefix.address().toString()));
-                }
-                break;
-            case IPV6_SRC:
-                ip = (IPCriterion) c;
-                ip6Prefix = ip.ip().getIp6Prefix();
-                if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
-                    Ip6Address maskAddr =
-                            Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
-                    Masked<IPv6Address> maskedIp =
-                            Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
-                                    IPv6Address.of(maskAddr.toString()));
-                    mBuilder.setMasked(MatchField.IPV6_SRC, maskedIp);
-                } else {
-                    mBuilder.setExact(MatchField.IPV6_SRC,
-                            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:
             case ARP_THA:
             case ARP_TPA:
-            case ICMPV4_CODE:
-            case ICMPV4_TYPE:
             case IN_PHY_PORT:
             case IPV6_EXTHDR:
-            case IPV6_FLABEL:
-            case IPV6_ND_SLL:
-            case IPV6_ND_TARGET:
-            case IPV6_ND_TLL:
             case IP_DSCP:
             case IP_ECN:
             case METADATA:
             case MPLS_BOS:
             case MPLS_TC:
             case PBB_ISID:
-            case SCTP_DST:
-            case SCTP_SRC:
             case TUNNEL_ID:
-            case UDP_DST:
-            case UDP_SRC:
             default:
                 log.warn("Match type {} not yet implemented.", c.type());
             }
diff --git a/web/api/src/main/java/org/onosproject/codec/impl/CriterionCodec.java b/web/api/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
index e6fbea8..0905432 100644
--- a/web/api/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
+++ b/web/api/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
@@ -44,11 +44,11 @@
 
             case IN_PORT:
                 final Criteria.PortCriterion portCriterion = (Criteria.PortCriterion) criterion;
-                result.put("tcpPort", portCriterion.port().toLong());
+                result.put("port", portCriterion.port().toLong());
                 break;
 
-            case ETH_SRC:
             case ETH_DST:
+            case ETH_SRC:
                 final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
                 result.put("mac", ethCriterion.mac().toString());
                 break;
@@ -59,18 +59,10 @@
                 result.put("ethType", ethTypeCriterion.ethType());
                 break;
 
-            case IPV4_SRC:
-            case IPV6_SRC:
-            case IPV4_DST:
-            case IPV6_DST:
-                final Criteria.IPCriterion iPCriterion = (Criteria.IPCriterion) criterion;
-                result.put("ip", iPCriterion.ip().toString());
-                break;
-
-            case IP_PROTO:
-                final Criteria.IPProtocolCriterion iPProtocolCriterion =
-                        (Criteria.IPProtocolCriterion) criterion;
-                result.put("protocol", iPProtocolCriterion.protocol());
+            case VLAN_VID:
+                final Criteria.VlanIdCriterion vlanIdCriterion =
+                        (Criteria.VlanIdCriterion) criterion;
+                result.put("vlanId", vlanIdCriterion.vlanId().toShort());
                 break;
 
             case VLAN_PCP:
@@ -79,10 +71,18 @@
                 result.put("priority", vlanPcpCriterion.priority());
                 break;
 
-            case VLAN_VID:
-                final Criteria.VlanIdCriterion vlanIdCriterion =
-                        (Criteria.VlanIdCriterion) criterion;
-                result.put("vlanId", vlanIdCriterion.vlanId().toShort());
+            case IP_PROTO:
+                final Criteria.IPProtocolCriterion iPProtocolCriterion =
+                        (Criteria.IPProtocolCriterion) criterion;
+                result.put("protocol", iPProtocolCriterion.protocol());
+                break;
+
+            case IPV4_SRC:
+            case IPV4_DST:
+            case IPV6_SRC:
+            case IPV6_DST:
+                final Criteria.IPCriterion iPCriterion = (Criteria.IPCriterion) criterion;
+                result.put("ip", iPCriterion.ip().toString());
                 break;
 
             case TCP_SRC:
@@ -92,6 +92,67 @@
                 result.put("tcpPort", tcpPortCriterion.tcpPort().byteValue());
                 break;
 
+            case UDP_SRC:
+            case UDP_DST:
+                final Criteria.UdpPortCriterion udpPortCriterion =
+                        (Criteria.UdpPortCriterion) criterion;
+                result.put("udpPort", udpPortCriterion.udpPort().byteValue());
+                break;
+
+            case SCTP_SRC:
+            case SCTP_DST:
+                final Criteria.SctpPortCriterion sctpPortCriterion =
+                        (Criteria.SctpPortCriterion) criterion;
+                result.put("sctpPort",
+                           sctpPortCriterion.sctpPort().byteValue());
+                break;
+
+            case ICMPV4_TYPE:
+                final Criteria.IcmpTypeCriterion icmpTypeCriterion =
+                        (Criteria.IcmpTypeCriterion) criterion;
+                result.put("icmpType", icmpTypeCriterion.icmpType());
+                break;
+
+            case ICMPV4_CODE:
+                final Criteria.IcmpCodeCriterion icmpCodeCriterion =
+                        (Criteria.IcmpCodeCriterion) criterion;
+                result.put("icmpCode", icmpCodeCriterion.icmpCode());
+                break;
+
+            case IPV6_FLABEL:
+                final Criteria.IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
+                        (Criteria.IPv6FlowLabelCriterion) criterion;
+                result.put("flowLabel",
+                           ipv6FlowLabelCriterion.flowLabel());
+                break;
+
+            case ICMPV6_TYPE:
+                final Criteria.Icmpv6TypeCriterion icmpv6TypeCriterion =
+                        (Criteria.Icmpv6TypeCriterion) criterion;
+                result.put("icmpv6Type", icmpv6TypeCriterion.icmpv6Type());
+                break;
+
+            case ICMPV6_CODE:
+                final Criteria.Icmpv6CodeCriterion icmpv6CodeCriterion =
+                        (Criteria.Icmpv6CodeCriterion) criterion;
+                result.put("icmpv6Code", icmpv6CodeCriterion.icmpv6Code());
+                break;
+
+            case IPV6_ND_TARGET:
+                final Criteria.IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
+                    = (Criteria.IPv6NDTargetAddressCriterion) criterion;
+                result.put("targetAddress",
+                           ipv6NDTargetAddressCriterion.targetAddress().toString());
+                break;
+
+            case IPV6_ND_SLL:
+            case IPV6_ND_TLL:
+                final Criteria.IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
+                    = (Criteria.IPv6NDLinkLayerAddressCriterion) criterion;
+                result.put("mac",
+                           ipv6NDLinkLayerAddressCriterion.mac().toString());
+                break;
+
             case MPLS_LABEL:
                 final Criteria.MplsCriterion mplsCriterion =
                         (Criteria.MplsCriterion) criterion;
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java b/web/api/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java
index e0baf87..b8c430c 100644
--- a/web/api/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java
+++ b/web/api/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java
@@ -33,6 +33,7 @@
         criterion = criterionValue;
     }
 
+    // CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES
     @Override
     public boolean matchesSafely(JsonNode jsonCriterion, Description description) {
         final String type = criterion.type().name();
@@ -54,8 +55,8 @@
                 }
                 break;
 
-            case ETH_SRC:
             case ETH_DST:
+            case ETH_SRC:
                 final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
                 final String mac = ethCriterion.mac().toString();
                 final String jsonMac = jsonCriterion.get("mac").textValue();
@@ -76,15 +77,24 @@
                 }
                 break;
 
-            case IPV4_SRC:
-            case IPV6_SRC:
-            case IPV4_DST:
-            case IPV6_DST:
-                final Criteria.IPCriterion ipCriterion = (Criteria.IPCriterion) criterion;
-                final String ip = ipCriterion.ip().toString();
-                final String jsonIp = jsonCriterion.get("ip").textValue();
-                if (!ip.equals(jsonIp)) {
-                    description.appendText("ip was " + jsonIp);
+            case VLAN_VID:
+                final Criteria.VlanIdCriterion vlanIdCriterion =
+                        (Criteria.VlanIdCriterion) criterion;
+                final short vlanId = vlanIdCriterion.vlanId().toShort();
+                final short jsonVlanId = jsonCriterion.get("vlanId").shortValue();
+                if (vlanId != jsonVlanId) {
+                    description.appendText("vlanId was " + Short.toString(jsonVlanId));
+                    return false;
+                }
+                break;
+
+            case VLAN_PCP:
+                final Criteria.VlanPcpCriterion vlanPcpCriterion =
+                        (Criteria.VlanPcpCriterion) criterion;
+                final byte priority = vlanPcpCriterion.priority();
+                final byte jsonPriority = (byte) jsonCriterion.get("priority").shortValue();
+                if (priority != jsonPriority) {
+                    description.appendText("priority was " + Byte.toString(jsonPriority));
                     return false;
                 }
                 break;
@@ -100,24 +110,15 @@
                 }
                 break;
 
-            case VLAN_PCP:
-                final Criteria.VlanPcpCriterion vlanPcpCriterion =
-                        (Criteria.VlanPcpCriterion) criterion;
-                final byte priority = vlanPcpCriterion.priority();
-                final byte jsonPriority = (byte) jsonCriterion.get("protocol").shortValue();
-                if (priority != jsonPriority) {
-                    description.appendText("priority was " + Byte.toString(jsonPriority));
-                    return false;
-                }
-                break;
-
-            case VLAN_VID:
-                final Criteria.VlanIdCriterion vlanIdCriterion =
-                        (Criteria.VlanIdCriterion) criterion;
-                final short vlanId = vlanIdCriterion.vlanId().toShort();
-                final short jsonvlanId = jsonCriterion.get("vlanId").shortValue();
-                if (vlanId != jsonvlanId) {
-                    description.appendText("vlanId was " + Short.toString(jsonvlanId));
+            case IPV4_SRC:
+            case IPV4_DST:
+            case IPV6_SRC:
+            case IPV6_DST:
+                final Criteria.IPCriterion ipCriterion = (Criteria.IPCriterion) criterion;
+                final String ip = ipCriterion.ip().toString();
+                final String jsonIp = jsonCriterion.get("ip").textValue();
+                if (!ip.equals(jsonIp)) {
+                    description.appendText("ip was " + jsonIp);
                     return false;
                 }
                 break;
@@ -126,10 +127,119 @@
             case TCP_DST:
                 final Criteria.TcpPortCriterion tcpPortCriterion =
                         (Criteria.TcpPortCriterion) criterion;
-                final byte tcpPort = tcpPortCriterion.tcpPort().byteValue();
-                final byte jsonTcpPort = (byte) jsonCriterion.get("tcpPort").shortValue();
+                final short tcpPort = tcpPortCriterion.tcpPort();
+                final short jsonTcpPort = jsonCriterion.get("tcpPort").shortValue();
                 if (tcpPort != jsonTcpPort) {
-                    description.appendText("tcp port was " + Byte.toString(jsonTcpPort));
+                    description.appendText("tcp port was " + Short.toString(jsonTcpPort));
+                    return false;
+                }
+                break;
+
+            case UDP_SRC:
+            case UDP_DST:
+                final Criteria.UdpPortCriterion udpPortCriterion =
+                        (Criteria.UdpPortCriterion) criterion;
+                final short udpPort = udpPortCriterion.udpPort();
+                final short jsonUdpPort = jsonCriterion.get("udpPort").shortValue();
+                if (udpPort != jsonUdpPort) {
+                    description.appendText("udp port was " + Short.toString(jsonUdpPort));
+                    return false;
+                }
+                break;
+
+            case SCTP_SRC:
+            case SCTP_DST:
+                final Criteria.SctpPortCriterion sctpPortCriterion =
+                        (Criteria.SctpPortCriterion) criterion;
+                final short sctpPort = sctpPortCriterion.sctpPort();
+                final short jsonSctpPort = jsonCriterion.get("sctpPort").shortValue();
+                if (sctpPort != jsonSctpPort) {
+                    description.appendText("sctp port was " + Short.toString(jsonSctpPort));
+                    return false;
+                }
+                break;
+
+            case ICMPV4_TYPE:
+                final Criteria.IcmpTypeCriterion icmpTypeCriterion =
+                        (Criteria.IcmpTypeCriterion) criterion;
+                final byte icmpType = icmpTypeCriterion.icmpType();
+                final byte jsonIcmpType = (byte) jsonCriterion.get("icmpType").shortValue();
+                if (icmpType != jsonIcmpType) {
+                    description.appendText("icmp type was " + Byte.toString(jsonIcmpType));
+                    return false;
+                }
+                break;
+
+            case ICMPV4_CODE:
+                final Criteria.IcmpCodeCriterion icmpCodeCriterion =
+                        (Criteria.IcmpCodeCriterion) criterion;
+                final byte icmpCode = icmpCodeCriterion.icmpCode();
+                final byte jsonIcmpCode = (byte) jsonCriterion.get("icmpCode").shortValue();
+                if (icmpCode != jsonIcmpCode) {
+                    description.appendText("icmp code was " + Byte.toString(jsonIcmpCode));
+                    return false;
+                }
+                break;
+
+            case IPV6_FLABEL:
+                final Criteria.IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
+                        (Criteria.IPv6FlowLabelCriterion) criterion;
+                final int flowLabel = ipv6FlowLabelCriterion.flowLabel();
+                final int jsonFlowLabel = jsonCriterion.get("flowLabel").intValue();
+                if (flowLabel != jsonFlowLabel) {
+                    description.appendText("IPv6 flow label was " + Integer.toString(jsonFlowLabel));
+                    return false;
+                }
+                break;
+
+            case ICMPV6_TYPE:
+                final Criteria.Icmpv6TypeCriterion icmpv6TypeCriterion =
+                        (Criteria.Icmpv6TypeCriterion) criterion;
+                final byte icmpv6Type = icmpv6TypeCriterion.icmpv6Type();
+                final byte jsonIcmpv6Type = (byte) jsonCriterion.get("icmpv6Type").shortValue();
+                if (icmpv6Type != jsonIcmpv6Type) {
+                    description.appendText("icmpv6 type was " + Byte.toString(jsonIcmpv6Type));
+                    return false;
+                }
+                break;
+
+            case ICMPV6_CODE:
+                final Criteria.Icmpv6CodeCriterion icmpv6CodeCriterion =
+                        (Criteria.Icmpv6CodeCriterion) criterion;
+                final byte icmpv6Code = icmpv6CodeCriterion.icmpv6Code();
+                final byte jsonIcmpv6Code = (byte) jsonCriterion.get("icmpv6Code").shortValue();
+                if (icmpv6Code != jsonIcmpv6Code) {
+                    description.appendText("icmpv6 code was " + Byte.toString(jsonIcmpv6Code));
+                    return false;
+                }
+                break;
+
+            case IPV6_ND_TARGET:
+                final Criteria.IPv6NDTargetAddressCriterion
+                    ipv6NDTargetAddressCriterion =
+                    (Criteria.IPv6NDTargetAddressCriterion) criterion;
+                final String targetAddress =
+                    ipv6NDTargetAddressCriterion.targetAddress().toString();
+                final String jsonTargetAddress =
+                    jsonCriterion.get("targetAddress").textValue();
+                if (!targetAddress.equals(jsonTargetAddress)) {
+                    description.appendText("target address was " +
+                                           jsonTargetAddress);
+                    return false;
+                }
+                break;
+
+            case IPV6_ND_SLL:
+            case IPV6_ND_TLL:
+                final Criteria.IPv6NDLinkLayerAddressCriterion
+                    ipv6NDLinkLayerAddressCriterion =
+                    (Criteria.IPv6NDLinkLayerAddressCriterion) criterion;
+                final String llAddress =
+                    ipv6NDLinkLayerAddressCriterion.mac().toString();
+                final String jsonLlAddress =
+                    jsonCriterion.get("mac").textValue();
+                if (!llAddress.equals(jsonLlAddress)) {
+                    description.appendText("mac was " + jsonLlAddress);
                     return false;
                 }
                 break;