[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;