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/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());
             }