[ONOS-5939] added traffic selector bitwise match on TCP/UDP/SCTP source/destination port

Change-Id: Ibf5947f7a6cac86fab77d15990116040fd8e5ef5
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 1cb6a64..0b93c52 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
@@ -263,31 +263,61 @@
         }
 
         @Override
+        public TrafficSelector.Builder matchTcpSrcMasked(TpPort tcpPort, TpPort mask) {
+            return add(Criteria.matchTcpSrcMasked(tcpPort, mask));
+        }
+
+        @Override
         public Builder matchTcpDst(TpPort tcpPort) {
             return add(Criteria.matchTcpDst(tcpPort));
         }
 
         @Override
+        public TrafficSelector.Builder matchTcpDstMasked(TpPort tcpPort, TpPort mask) {
+            return add(Criteria.matchTcpDstMasked(tcpPort, mask));
+        }
+
+        @Override
         public Builder matchUdpSrc(TpPort udpPort) {
             return add(Criteria.matchUdpSrc(udpPort));
         }
 
         @Override
+        public TrafficSelector.Builder matchUdpSrcMasked(TpPort udpPort, TpPort mask) {
+            return add(Criteria.matchUdpSrcMasked(udpPort, mask));
+        }
+
+        @Override
         public Builder matchUdpDst(TpPort udpPort) {
             return add(Criteria.matchUdpDst(udpPort));
         }
 
         @Override
+        public TrafficSelector.Builder matchUdpDstMasked(TpPort udpPort, TpPort mask) {
+            return add(Criteria.matchUdpDstMasked(udpPort, mask));
+        }
+
+        @Override
         public Builder matchSctpSrc(TpPort sctpPort) {
             return add(Criteria.matchSctpSrc(sctpPort));
         }
 
         @Override
+        public TrafficSelector.Builder matchSctpSrcMasked(TpPort sctpPort, TpPort mask) {
+            return add(Criteria.matchSctpSrcMasked(sctpPort, mask));
+        }
+
+        @Override
         public Builder matchSctpDst(TpPort sctpPort) {
             return add(Criteria.matchSctpDst(sctpPort));
         }
 
         @Override
+        public TrafficSelector.Builder matchSctpDstMasked(TpPort sctpPort, TpPort mask) {
+            return add(Criteria.matchSctpDstMasked(sctpPort, mask));
+        }
+
+        @Override
         public Builder matchIcmpType(byte icmpType) {
             return add(Criteria.matchIcmpType(icmpType));
         }
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 6a018c3..1b264b5 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
@@ -211,6 +211,15 @@
         Builder matchTcpSrc(TpPort tcpPort);
 
         /**
+         * Matches a TCP source port number with mask.
+         *
+         * @param tcpPort a TCP source port number
+         * @param mask a mask for a TCP source port number
+         * @return a selection builder
+         */
+        Builder matchTcpSrcMasked(TpPort tcpPort, TpPort mask);
+
+        /**
          * Matches a TCP destination port number.
          *
          * @param tcpPort a TCP destination port number
@@ -219,6 +228,15 @@
         Builder matchTcpDst(TpPort tcpPort);
 
         /**
+         * Matches a TCP destination port number with mask.
+         *
+         * @param tcpPort a TCP destination port number
+         * @param mask a mask for a TCP destination port number
+         * @return a selection builder
+         */
+        Builder matchTcpDstMasked(TpPort tcpPort, TpPort mask);
+
+        /**
          * Matches an UDP source port number.
          *
          * @param udpPort an UDP source port number
@@ -227,6 +245,15 @@
         Builder matchUdpSrc(TpPort udpPort);
 
         /**
+         * Matches a UDP source port number with mask.
+         *
+         * @param udpPort a UDP source port number
+         * @param mask a mask for a UDP source port number
+         * @return a selection builder
+         */
+        Builder matchUdpSrcMasked(TpPort udpPort, TpPort mask);
+
+        /**
          * Matches an UDP destination port number.
          *
          * @param udpPort an UDP destination port number
@@ -235,6 +262,15 @@
         Builder matchUdpDst(TpPort udpPort);
 
         /**
+         * Matches a UDP destination port number with mask.
+         *
+         * @param udpPort a UDP destination port number
+         * @param mask a mask for a UDP destination port number
+         * @return a selection builder
+         */
+        Builder matchUdpDstMasked(TpPort udpPort, TpPort mask);
+
+        /**
          * Matches a SCTP source port number.
          *
          * @param sctpPort a SCTP source port number
@@ -243,6 +279,15 @@
         Builder matchSctpSrc(TpPort sctpPort);
 
         /**
+         * Matches a SCTP source port number with mask.
+         *
+         * @param sctpPort a SCTP source port number
+         * @param mask a mask for a SCTP source port number
+         * @return a selection builder
+         */
+        Builder matchSctpSrcMasked(TpPort sctpPort, TpPort mask);
+
+        /**
          * Matches a SCTP destination port number.
          *
          * @param sctpPort a SCTP destination port number
@@ -251,6 +296,15 @@
         Builder matchSctpDst(TpPort sctpPort);
 
         /**
+         * Matches a SCTP destination port number with mask.
+         *
+         * @param sctpPort a SCTP destination port number
+         * @param mask a mask for a SCTP destination port number
+         * @return a selection builder
+         */
+        Builder matchSctpDstMasked(TpPort sctpPort, TpPort mask);
+
+        /**
          * Matches an ICMP type.
          *
          * @param icmpType an ICMP type
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 88ab0e6..f38b442 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
@@ -238,6 +238,17 @@
     }
 
     /**
+     * Creates a masked match on TCP source port field using the specified value and mask.
+     *
+     * @param tcpPort TCP source port
+     * @param mask TCP source port masking
+     * @return match criterion
+     */
+    public static Criterion matchTcpSrcMasked(TpPort tcpPort, TpPort mask) {
+        return new TcpPortCriterion(tcpPort, mask, Type.TCP_SRC_MASKED);
+    }
+
+    /**
      * Creates a match on TCP destination port field using the specified value.
      *
      * @param tcpPort TCP destination port
@@ -248,6 +259,17 @@
     }
 
     /**
+     * Creates a masked match on TCP destination port field using the specified value and mask.
+     *
+     * @param tcpPort TCP destination port
+     * @param mask TCP destination port masking
+     * @return match criterion
+     */
+    public static Criterion matchTcpDstMasked(TpPort tcpPort, TpPort mask) {
+        return new TcpPortCriterion(tcpPort, mask, Type.TCP_DST_MASKED);
+    }
+
+    /**
      * Creates a match on TCP flags using the specified value.
      *
      * @param flags TCP flags
@@ -268,6 +290,17 @@
     }
 
     /**
+     * Creates a masked match on UDP source port field using the specified value and mask.
+     *
+     * @param udpPort UDP source port
+     * @param mask UDP source port masking
+     * @return match criterion
+     */
+    public static Criterion matchUdpSrcMasked(TpPort udpPort, TpPort mask) {
+        return new UdpPortCriterion(udpPort, mask, Type.UDP_SRC_MASKED);
+    }
+
+    /**
      * Creates a match on UDP destination port field using the specified value.
      *
      * @param udpPort UDP destination port
@@ -278,6 +311,17 @@
     }
 
     /**
+     * Creates a masked match on UDP destination port field using the specified value and mask.
+     *
+     * @param udpPort UDP destination port
+     * @param mask UDP destination port masking
+     * @return match criterion
+     */
+    public static Criterion matchUdpDstMasked(TpPort udpPort, TpPort mask) {
+        return new UdpPortCriterion(udpPort, mask, Type.UDP_DST_MASKED);
+    }
+
+    /**
      * Creates a match on SCTP source port field using the specified value.
      *
      * @param sctpPort SCTP source port
@@ -288,6 +332,17 @@
     }
 
     /**
+     * Creates a masked match on SCTP source port field using the specified value and mask.
+     *
+     * @param sctpPort SCTP source port
+     * @param mask SCTP source port masking
+     * @return match criterion
+     */
+    public static Criterion matchSctpSrcMasked(TpPort sctpPort, TpPort mask) {
+        return new SctpPortCriterion(sctpPort, mask, Type.SCTP_SRC_MASKED);
+    }
+
+    /**
      * Creates a match on SCTP destination port field using the specified
      * value.
      *
@@ -299,6 +354,17 @@
     }
 
     /**
+     * Creates a masked match on SCTP destination port field using the specified value and mask.
+     *
+     * @param sctpPort SCTP destination port
+     * @param mask SCTP destination port masking
+     * @return match criterion
+     */
+    public static Criterion matchSctpDstMasked(TpPort sctpPort, TpPort mask) {
+        return new SctpPortCriterion(sctpPort, mask, Type.SCTP_DST_MASKED);
+    }
+
+    /**
      * Creates a match on ICMP type field using the specified value.
      *
      * @param icmpType ICMP type (8 bits unsigned integer)
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 4772a35..a8aba57 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
@@ -90,21 +90,39 @@
         /** TCP source port. */
         TCP_SRC,
 
+        /** TCP source port with masking. */
+        TCP_SRC_MASKED,
+
         /** TCP destination port. */
         TCP_DST,
 
+        /** TCP destination port with masking. */
+        TCP_DST_MASKED,
+
         /** UDP source port. */
         UDP_SRC,
 
+        /** UDP source port with masking. */
+        UDP_SRC_MASKED,
+
         /** UDP destination port. */
         UDP_DST,
 
+        /** UDP destination port with masking. */
+        UDP_DST_MASKED,
+
         /** SCTP source port. */
         SCTP_SRC,
 
+        /** SCTP source port with masking. */
+        SCTP_SRC_MASKED,
+
         /** SCTP destination port. */
         SCTP_DST,
 
+        /** SCTP destination port with masking. */
+        SCTP_DST_MASKED,
+
         /** ICMP type. */
         ICMPV4_TYPE,
 
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java
index ef3a37e..ca5d1d5 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java
@@ -24,18 +24,32 @@
  */
 public final class SctpPortCriterion implements Criterion {
     private final TpPort sctpPort;
+    private final TpPort mask;
     private final Type type;
 
     /**
      * Constructor.
      *
      * @param sctpPort the SCTP port to match
+     * @param mask the mask for the SCTP port
+     * @param type the match type. Should be either Type.SCTP_SRC_MASKED or
+     * Type.SCTP_SRC_DST_MASKED
+     */
+    SctpPortCriterion(TpPort sctpPort, TpPort mask, Type type) {
+        this.sctpPort = sctpPort;
+        this.mask = mask;
+        this.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
      */
     SctpPortCriterion(TpPort sctpPort, Type type) {
-        this.sctpPort = sctpPort;
-        this.type = type;
+        this(sctpPort, null, type);
     }
 
     @Override
@@ -52,14 +66,25 @@
         return this.sctpPort;
     }
 
+    /**
+     * Gets the mask for the SCTP port to match.
+     *
+     * @return the SCTP port mask, null if not specified
+     */
+    public TpPort mask() {
+        return this.mask;
+    }
+
     @Override
     public String toString() {
-        return type().toString() + SEPARATOR + sctpPort;
+        return (mask != null) ?
+                type().toString() + SEPARATOR + sctpPort + "/" + mask :
+                type().toString() + SEPARATOR + sctpPort;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(type().ordinal(), sctpPort);
+        return Objects.hash(type.ordinal(), sctpPort, mask);
     }
 
     @Override
@@ -70,6 +95,7 @@
         if (obj instanceof SctpPortCriterion) {
             SctpPortCriterion that = (SctpPortCriterion) obj;
             return Objects.equals(sctpPort, that.sctpPort) &&
+                    Objects.equals(mask, that.mask) &&
                     Objects.equals(type, that.type);
         }
         return false;
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java
index f794ae1..91b0cc2 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java
@@ -24,18 +24,32 @@
  */
 public final class TcpPortCriterion implements Criterion {
     private final TpPort tcpPort;
+    private final TpPort mask;
     private final Type type;
 
     /**
      * Constructor.
      *
      * @param tcpPort the TCP port to match
+     * @param mask the mask for the TCP port
+     * @param type the match type. Should be either Type.TCP_SRC_MASKED or
+     * Type.TCP_DST_MASKED
+     */
+    TcpPortCriterion(TpPort tcpPort, TpPort mask, Type type) {
+        this.tcpPort = tcpPort;
+        this.mask = mask;
+        this.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
      */
     TcpPortCriterion(TpPort tcpPort, Type type) {
-        this.tcpPort = tcpPort;
-        this.type = type;
+        this(tcpPort, null, type);
     }
 
     @Override
@@ -52,14 +66,25 @@
         return this.tcpPort;
     }
 
+    /**
+     * Gets the mask for the TCP port to match.
+     *
+     * @return the TCP port mask, null if not specified
+     */
+    public TpPort mask() {
+        return this.mask;
+    }
+
     @Override
     public String toString() {
-        return type().toString() + SEPARATOR + tcpPort;
+        return (mask != null) ?
+                type().toString() + SEPARATOR + tcpPort + "/" + mask :
+                type().toString() + SEPARATOR + tcpPort;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(type().ordinal(), tcpPort);
+        return Objects.hash(type.ordinal(), tcpPort, mask);
     }
 
     @Override
@@ -70,6 +95,7 @@
         if (obj instanceof TcpPortCriterion) {
             TcpPortCriterion that = (TcpPortCriterion) obj;
             return Objects.equals(tcpPort, that.tcpPort) &&
+                    Objects.equals(mask, that.mask) &&
                     Objects.equals(type, that.type);
         }
         return false;
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java
index bec8151..6d7bc4b 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java
@@ -24,18 +24,32 @@
  */
 public final class UdpPortCriterion implements Criterion {
     private final TpPort udpPort;
+    private final TpPort mask;
     private final Type type;
 
     /**
      * Constructor.
      *
      * @param udpPort the UDP port to match
+     * @param mask the mask for the UDP port
+     * @param type the match type. Should be either Type.UDP_SRC_MASKED or
+     * Type.UDP_DST_MASKED
+     */
+    UdpPortCriterion(TpPort udpPort, TpPort mask, Type type) {
+        this.udpPort = udpPort;
+        this.mask = mask;
+        this.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
      */
     UdpPortCriterion(TpPort udpPort, Type type) {
-        this.udpPort = udpPort;
-        this.type = type;
+        this(udpPort, null, type);
     }
 
     @Override
@@ -52,14 +66,25 @@
         return this.udpPort;
     }
 
+    /**
+     * Gets the mask for the UDP port to match.
+     *
+     * @return the UDP port mask, null if not specified
+     */
+    public TpPort mask() {
+        return this.mask;
+    }
+
     @Override
     public String toString() {
-        return type().toString() + SEPARATOR + udpPort;
+        return (mask != null) ?
+                type().toString() + SEPARATOR + udpPort + "/" + mask :
+                type().toString() + SEPARATOR + udpPort;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(type().ordinal(), udpPort);
+        return Objects.hash(type.ordinal(), udpPort, mask);
     }
 
     @Override
@@ -70,6 +95,7 @@
         if (obj instanceof UdpPortCriterion) {
             UdpPortCriterion that = (UdpPortCriterion) obj;
             return Objects.equals(udpPort, that.udpPort) &&
+                    Objects.equals(mask, that.mask) &&
                     Objects.equals(type, that.type);
         }
         return false;
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
index f13996f..0010848 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
@@ -132,6 +132,12 @@
         formatMap.put(Criterion.Type.EXTENSION, new FormatUnknown());
         formatMap.put(Criterion.Type.ETH_DST_MASKED, new FormatUnknown());
         formatMap.put(Criterion.Type.ETH_SRC_MASKED, new FormatUnknown());
+        formatMap.put(Criterion.Type.TCP_SRC_MASKED, new FormatUnknown());
+        formatMap.put(Criterion.Type.TCP_DST_MASKED, new FormatUnknown());
+        formatMap.put(Criterion.Type.UDP_SRC_MASKED, new FormatUnknown());
+        formatMap.put(Criterion.Type.UDP_DST_MASKED, new FormatUnknown());
+        formatMap.put(Criterion.Type.SCTP_SRC_MASKED, new FormatUnknown());
+        formatMap.put(Criterion.Type.SCTP_DST_MASKED, new FormatUnknown());
 
     }
 
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 d025180..02ebebe 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
@@ -308,31 +308,67 @@
                 mBuilder.setExact(MatchField.TCP_SRC,
                                   TransportPort.of(tcpPortCriterion.tcpPort().toInt()));
                 break;
+            case TCP_SRC_MASKED:
+                tcpPortCriterion = (TcpPortCriterion) c;
+                mBuilder.setMasked(MatchField.TCP_SRC,
+                                   TransportPort.of(tcpPortCriterion.tcpPort().toInt()),
+                                   TransportPort.of(tcpPortCriterion.mask().toInt()));
+                break;
             case TCP_DST:
                 tcpPortCriterion = (TcpPortCriterion) c;
                 mBuilder.setExact(MatchField.TCP_DST,
                                   TransportPort.of(tcpPortCriterion.tcpPort().toInt()));
                 break;
+            case TCP_DST_MASKED:
+                tcpPortCriterion = (TcpPortCriterion) c;
+                mBuilder.setMasked(MatchField.TCP_DST,
+                                   TransportPort.of(tcpPortCriterion.tcpPort().toInt()),
+                                   TransportPort.of(tcpPortCriterion.mask().toInt()));
+                break;
             case UDP_SRC:
                 udpPortCriterion = (UdpPortCriterion) c;
                 mBuilder.setExact(MatchField.UDP_SRC,
                                   TransportPort.of(udpPortCriterion.udpPort().toInt()));
                 break;
+            case UDP_SRC_MASKED:
+                udpPortCriterion = (UdpPortCriterion) c;
+                mBuilder.setMasked(MatchField.UDP_SRC,
+                                   TransportPort.of(udpPortCriterion.udpPort().toInt()),
+                                   TransportPort.of(udpPortCriterion.mask().toInt()));
+                break;
             case UDP_DST:
                 udpPortCriterion = (UdpPortCriterion) c;
                 mBuilder.setExact(MatchField.UDP_DST,
                                   TransportPort.of(udpPortCriterion.udpPort().toInt()));
                 break;
+            case UDP_DST_MASKED:
+                udpPortCriterion = (UdpPortCriterion) c;
+                mBuilder.setMasked(MatchField.UDP_DST,
+                                   TransportPort.of(udpPortCriterion.udpPort().toInt()),
+                                   TransportPort.of(udpPortCriterion.mask().toInt()));
+                break;
             case SCTP_SRC:
                 sctpPortCriterion = (SctpPortCriterion) c;
                 mBuilder.setExact(MatchField.SCTP_SRC,
                                   TransportPort.of(sctpPortCriterion.sctpPort().toInt()));
                 break;
+            case SCTP_SRC_MASKED:
+                sctpPortCriterion = (SctpPortCriterion) c;
+                mBuilder.setMasked(MatchField.SCTP_SRC,
+                                   TransportPort.of(sctpPortCriterion.sctpPort().toInt()),
+                                   TransportPort.of(sctpPortCriterion.mask().toInt()));
+                break;
             case SCTP_DST:
                 sctpPortCriterion = (SctpPortCriterion) c;
                 mBuilder.setExact(MatchField.SCTP_DST,
                                   TransportPort.of(sctpPortCriterion.sctpPort().toInt()));
                 break;
+            case SCTP_DST_MASKED:
+                sctpPortCriterion = (SctpPortCriterion) c;
+                mBuilder.setMasked(MatchField.SCTP_DST,
+                                   TransportPort.of(sctpPortCriterion.sctpPort().toInt()),
+                                   TransportPort.of(sctpPortCriterion.mask().toInt()));
+                break;
             case ICMPV4_TYPE:
                 IcmpTypeCriterion icmpType = (IcmpTypeCriterion) c;
                 mBuilder.setExact(MatchField.ICMPV4_TYPE,
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
index c68c173..76be182 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
@@ -813,16 +813,44 @@
                 builder.matchIPDst(ip4Prefix);
                 break;
             case TCP_SRC:
-                builder.matchTcpSrc(TpPort.tpPort(match.get(MatchField.TCP_SRC).getPort()));
+                if (match.isPartiallyMasked(MatchField.TCP_SRC)) {
+                    Masked<org.projectfloodlight.openflow.types.TransportPort> maskedPort =
+                            match.getMasked(MatchField.TCP_SRC);
+                    builder.matchTcpSrcMasked(TpPort.tpPort(maskedPort.getValue().getPort()),
+                                              TpPort.tpPort(maskedPort.getMask().getPort()));
+                } else {
+                    builder.matchTcpSrc(TpPort.tpPort(match.get(MatchField.TCP_SRC).getPort()));
+                }
                 break;
             case TCP_DST:
-                builder.matchTcpDst(TpPort.tpPort(match.get(MatchField.TCP_DST).getPort()));
+                if (match.isPartiallyMasked(MatchField.TCP_DST)) {
+                    Masked<org.projectfloodlight.openflow.types.TransportPort> maskedPort =
+                            match.getMasked(MatchField.TCP_DST);
+                    builder.matchTcpDstMasked(TpPort.tpPort(maskedPort.getValue().getPort()),
+                                              TpPort.tpPort(maskedPort.getMask().getPort()));
+                } else {
+                    builder.matchTcpDst(TpPort.tpPort(match.get(MatchField.TCP_DST).getPort()));
+                }
                 break;
             case UDP_SRC:
-                builder.matchUdpSrc(TpPort.tpPort(match.get(MatchField.UDP_SRC).getPort()));
+                if (match.isPartiallyMasked(MatchField.UDP_SRC)) {
+                    Masked<org.projectfloodlight.openflow.types.TransportPort> maskedPort =
+                            match.getMasked(MatchField.UDP_SRC);
+                    builder.matchUdpSrcMasked(TpPort.tpPort(maskedPort.getValue().getPort()),
+                                              TpPort.tpPort(maskedPort.getMask().getPort()));
+                } else {
+                    builder.matchUdpSrc(TpPort.tpPort(match.get(MatchField.UDP_SRC).getPort()));
+                }
                 break;
             case UDP_DST:
-                builder.matchUdpDst(TpPort.tpPort(match.get(MatchField.UDP_DST).getPort()));
+                if (match.isPartiallyMasked(MatchField.UDP_DST)) {
+                    Masked<org.projectfloodlight.openflow.types.TransportPort> maskedPort =
+                            match.getMasked(MatchField.UDP_DST);
+                    builder.matchUdpDstMasked(TpPort.tpPort(maskedPort.getValue().getPort()),
+                                              TpPort.tpPort(maskedPort.getMask().getPort()));
+                } else {
+                    builder.matchUdpDst(TpPort.tpPort(match.get(MatchField.UDP_DST).getPort()));
+                }
                 break;
             case MPLS_LABEL:
                 builder.matchMplsLabel(MplsLabel.mplsLabel((int) match.get(MatchField.MPLS_LABEL)
@@ -832,10 +860,24 @@
                 builder.matchMplsBos(match.get(MatchField.MPLS_BOS).getValue());
                 break;
             case SCTP_SRC:
-                builder.matchSctpSrc(TpPort.tpPort(match.get(MatchField.SCTP_SRC).getPort()));
+                if (match.isPartiallyMasked(MatchField.SCTP_SRC)) {
+                    Masked<org.projectfloodlight.openflow.types.TransportPort> maskedPort =
+                            match.getMasked(MatchField.SCTP_SRC);
+                    builder.matchSctpSrcMasked(TpPort.tpPort(maskedPort.getValue().getPort()),
+                                               TpPort.tpPort(maskedPort.getMask().getPort()));
+                } else {
+                    builder.matchSctpSrc(TpPort.tpPort(match.get(MatchField.SCTP_SRC).getPort()));
+                }
                 break;
             case SCTP_DST:
-                builder.matchSctpDst(TpPort.tpPort(match.get(MatchField.SCTP_DST).getPort()));
+                if (match.isPartiallyMasked(MatchField.SCTP_DST)) {
+                    Masked<org.projectfloodlight.openflow.types.TransportPort> maskedPort =
+                            match.getMasked(MatchField.SCTP_DST);
+                    builder.matchSctpDstMasked(TpPort.tpPort(maskedPort.getValue().getPort()),
+                                               TpPort.tpPort(maskedPort.getMask().getPort()));
+                } else {
+                    builder.matchSctpDst(TpPort.tpPort(match.get(MatchField.SCTP_DST).getPort()));
+                }
                 break;
             case ICMPV4_TYPE:
                 byte icmpType = (byte) match.get(MatchField.ICMPV4_TYPE).getType();