Implement some of the missing Selector and Match Conditions
Work toward ONOS-509
The following match conditions are added/implemented:
- IN_PHY_PORT
- IP_DSCP
- IP_ECN
- METADATA
Change-Id: I6f529ee90b2b9e0d5046f83c034e8be3faf86d8b
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 21b1832..aa9405db 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
@@ -135,6 +135,16 @@
}
@Override
+ public Builder matchInPhyPort(PortNumber port) {
+ return add(Criteria.matchInPhyPort(port));
+ }
+
+ @Override
+ public Builder matchMetadata(Long metadata) {
+ return add(Criteria.matchMetadata(metadata));
+ }
+
+ @Override
public Builder matchEthDst(MacAddress addr) {
return add(Criteria.matchEthDst(addr));
}
@@ -160,6 +170,16 @@
}
@Override
+ public Builder matchIPDscp(Byte ipDscp) {
+ return add(Criteria.matchIPDscp(ipDscp));
+ }
+
+ @Override
+ public Builder matchIPEcn(Byte ipEcn) {
+ return add(Criteria.matchIPEcn(ipEcn));
+ }
+
+ @Override
public Builder matchIPProtocol(Byte proto) {
return add(Criteria.matchIPProtocol(proto));
}
@@ -273,7 +293,5 @@
public TrafficSelector build() {
return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
}
-
}
-
}
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 e6fdeb2..1ecab71 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
@@ -68,6 +68,22 @@
public Builder matchInPort(PortNumber port);
/**
+ * Matches a physical inport.
+ *
+ * @param port the physical inport
+ * @return a selection builder
+ */
+ public Builder matchInPhyPort(PortNumber port);
+
+ /**
+ * Matches a metadata.
+ *
+ * @param metadata the metadata
+ * @return a selection builder
+ */
+ public Builder matchMetadata(Long metadata);
+
+ /**
* Matches a l2 dst address.
*
* @param addr a l2 address
@@ -108,6 +124,22 @@
public Builder matchVlanPcp(Byte vlanPcp);
/**
+ * Matches an IP DSCP (6 bits in ToS field).
+ *
+ * @param ipDscp an IP DSCP value
+ * @return a selection builder
+ */
+ public Builder matchIPDscp(Byte ipDscp);
+
+ /**
+ * Matches an IP ECN (2 bits in ToS field).
+ *
+ * @param ipEcn an IP ECN value
+ * @return a selection builder
+ */
+ public Builder matchIPEcn(Byte ipEcn);
+
+ /**
* Matches the l3 protocol.
*
* @param proto a l3 protocol
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 d4ec124..f972d9e 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
@@ -43,7 +43,27 @@
* @return match criterion
*/
public static Criterion matchInPort(PortNumber port) {
- return new PortCriterion(port);
+ return new PortCriterion(port, Type.IN_PORT);
+ }
+
+ /**
+ * Creates a match on IN_PHY_PORT field using the specified value.
+ *
+ * @param port inport value
+ * @return match criterion
+ */
+ public static Criterion matchInPhyPort(PortNumber port) {
+ return new PortCriterion(port, Type.IN_PHY_PORT);
+ }
+
+ /**
+ * Creates a match on METADATA field using the specified value.
+ *
+ * @param metadata metadata value
+ * @return match criterion
+ */
+ public static Criterion matchMetadata(Long metadata) {
+ return new MetadataCriterion(metadata);
}
/**
@@ -99,6 +119,26 @@
}
/**
+ * Creates a match on IP DSCP field using the specified value.
+ *
+ * @param ipDscp ip dscp value
+ * @return match criterion
+ */
+ public static Criterion matchIPDscp(Byte ipDscp) {
+ return new IPDscpCriterion(ipDscp);
+ }
+
+ /**
+ * Creates a match on IP ECN field using the specified value.
+ *
+ * @param ipEcn ip ecn value
+ * @return match criterion
+ */
+ public static Criterion matchIPEcn(Byte ipEcn) {
+ return new IPEcnCriterion(ipEcn);
+ }
+
+ /**
* Creates a match on IP proto field using the specified value.
*
* @param proto ip protocol value
@@ -327,19 +367,23 @@
*/
public static final class PortCriterion implements Criterion {
private final PortNumber port;
+ private final Type type;
/**
* Constructor.
*
* @param port the input port number to match
+ * @param type the match type. Should be either Type.IN_PORT or
+ * Type.IN_PHY_PORT
*/
- public PortCriterion(PortNumber port) {
+ public PortCriterion(PortNumber port, Type type) {
this.port = port;
+ this.type = type;
}
@Override
public Type type() {
- return Type.IN_PORT;
+ return this.type;
}
/**
@@ -371,7 +415,61 @@
PortCriterion that = (PortCriterion) obj;
return Objects.equals(port, that.port) &&
Objects.equals(this.type(), that.type());
+ }
+ return false;
+ }
+ }
+ /**
+ * Implementation of Metadata criterion.
+ */
+ public static final class MetadataCriterion implements Criterion {
+ private final Long metadata;
+
+ /**
+ * Constructor.
+ *
+ * @param metadata the metadata to match
+ */
+ public MetadataCriterion(Long metadata) {
+ this.metadata = metadata;
+ }
+
+ @Override
+ public Type type() {
+ return Type.METADATA;
+ }
+
+ /**
+ * Gets the metadata to match.
+ *
+ * @return the metadata to match
+ */
+ public Long metadata() {
+ return metadata;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("metadata", Long.toHexString(metadata))
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), metadata);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof MetadataCriterion) {
+ MetadataCriterion that = (MetadataCriterion) obj;
+ return Objects.equals(metadata, that.metadata) &&
+ Objects.equals(this.type(), that.type());
}
return false;
}
@@ -601,6 +699,118 @@
}
/**
+ * Implementation of IP DSCP criterion (6-bit Differentiated Services
+ * Code Point).
+ */
+ public static final class IPDscpCriterion implements Criterion {
+ private static final byte DSCP_MASK = 0x3f;
+ private final Byte ipDscp; // IP DSCP value: 6 bits
+
+ /**
+ * Constructor.
+ *
+ * @param ipDscp the IP DSCP value to match
+ */
+ public IPDscpCriterion(Byte ipDscp) {
+ this.ipDscp = (byte) (ipDscp & DSCP_MASK);
+ }
+
+ @Override
+ public Type type() {
+ return Type.IP_DSCP;
+ }
+
+ /**
+ * Gets the IP DSCP value to match.
+ *
+ * @return the IP DSCP value to match
+ */
+ public Byte ipDscp() {
+ return ipDscp;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("ipDscp", ipDscp).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), ipDscp);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof IPDscpCriterion) {
+ IPDscpCriterion that = (IPDscpCriterion) obj;
+ return Objects.equals(ipDscp, that.ipDscp) &&
+ Objects.equals(this.type(), that.type());
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Implementation of IP ECN criterion (3-bit Explicit Congestion
+ * Notification).
+ */
+ public static final class IPEcnCriterion implements Criterion {
+ private static final byte ECN_MASK = 0x3;
+ private final Byte ipEcn; // IP ECN value: 3 bits
+
+ /**
+ * Constructor.
+ *
+ * @param ipEcn the IP ECN value to match
+ */
+ public IPEcnCriterion(Byte ipEcn) {
+ this.ipEcn = (byte) (ipEcn & ECN_MASK);
+ }
+
+ @Override
+ public Type type() {
+ return Type.IP_ECN;
+ }
+
+ /**
+ * Gets the IP ECN value to match.
+ *
+ * @return the IP ECN value to match
+ */
+ public Byte ipEcn() {
+ return ipEcn;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("ipEcn", ipEcn).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), ipEcn);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof IPEcnCriterion) {
+ IPEcnCriterion that = (IPEcnCriterion) obj;
+ return Objects.equals(ipEcn, that.ipEcn) &&
+ Objects.equals(this.type(), that.type());
+ }
+ return false;
+ }
+ }
+
+ /**
* Implementation of Internet Protocol Number criterion.
*/
public static final class IPProtocolCriterion implements Criterion {
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 e232647..3fb62a7 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
@@ -127,9 +127,12 @@
public void testCriteriaCreation() {
TrafficSelector selector;
+ final long longValue = 0x12345678;
final int intValue = 22;
final short shortValue = 33;
final byte byteValue = 44;
+ final byte dscpValue = 0xf;
+ final byte ecnValue = 3;
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");
@@ -140,6 +143,14 @@
assertThat(selector, hasCriterionWithType(Type.IN_PORT));
selector = DefaultTrafficSelector.builder()
+ .matchInPhyPort(PortNumber.portNumber(11)).build();
+ assertThat(selector, hasCriterionWithType(Type.IN_PHY_PORT));
+
+ selector = DefaultTrafficSelector.builder()
+ .matchMetadata(longValue).build();
+ assertThat(selector, hasCriterionWithType(Type.METADATA));
+
+ selector = DefaultTrafficSelector.builder()
.matchEthDst(macValue).build();
assertThat(selector, hasCriterionWithType(Type.ETH_DST));
@@ -160,6 +171,14 @@
assertThat(selector, hasCriterionWithType(Type.VLAN_PCP));
selector = DefaultTrafficSelector.builder()
+ .matchIPDscp(dscpValue).build();
+ assertThat(selector, hasCriterionWithType(Type.IP_DSCP));
+
+ selector = DefaultTrafficSelector.builder()
+ .matchIPEcn(ecnValue).build();
+ assertThat(selector, hasCriterionWithType(Type.IP_ECN));
+
+ selector = DefaultTrafficSelector.builder()
.matchIPProtocol(byteValue).build();
assertThat(selector, hasCriterionWithType(Type.IP_PROTO));
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 3cebd8e..ba01133 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
@@ -45,6 +45,16 @@
Criterion sameAsMatchInPort1 = Criteria.matchInPort(port1);
Criterion matchInPort2 = Criteria.matchInPort(port2);
+ Criterion matchInPhyPort1 = Criteria.matchInPhyPort(port1);
+ Criterion sameAsMatchInPhyPort1 = Criteria.matchInPhyPort(port1);
+ Criterion matchInPhyPort2 = Criteria.matchInPhyPort(port2);
+
+ long metadata1 = 1;
+ long metadata2 = 2;
+ Criterion matchMetadata1 = Criteria.matchMetadata(metadata1);
+ Criterion sameAsMatchMetadata1 = Criteria.matchMetadata(metadata1);
+ Criterion matchMetadata2 = Criteria.matchMetadata(metadata2);
+
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 = MacAddress.valueOf(MAC1);
@@ -73,6 +83,18 @@
Criterion sameAsMatchVlanPcp1 = Criteria.matchVlanPcp(vlanPcp1);
Criterion matchVlanPcp2 = Criteria.matchVlanPcp(vlanPcp2);
+ byte ipDscp1 = 1;
+ byte ipDscp2 = 2;
+ Criterion matchIpDscp1 = Criteria.matchIPDscp(ipDscp1);
+ Criterion sameAsMatchIpDscp1 = Criteria.matchIPDscp(ipDscp1);
+ Criterion matchIpDscp2 = Criteria.matchIPDscp(ipDscp2);
+
+ byte ipEcn1 = 1;
+ byte ipEcn2 = 2;
+ Criterion matchIpEcn1 = Criteria.matchIPEcn(ipEcn1);
+ Criterion sameAsMatchIpEcn1 = Criteria.matchIPEcn(ipEcn1);
+ Criterion matchIpEcn2 = Criteria.matchIPEcn(ipEcn2);
+
byte protocol1 = 1;
byte protocol2 = 2;
Criterion matchIpProtocol1 = Criteria.matchIPProtocol(protocol1);
@@ -214,10 +236,13 @@
@Test
public void testCriteriaImmutability() {
assertThatClassIsImmutable(Criteria.PortCriterion.class);
+ assertThatClassIsImmutable(Criteria.MetadataCriterion.class);
assertThatClassIsImmutable(Criteria.EthCriterion.class);
assertThatClassIsImmutable(Criteria.EthTypeCriterion.class);
assertThatClassIsImmutable(Criteria.VlanIdCriterion.class);
assertThatClassIsImmutable(Criteria.VlanPcpCriterion.class);
+ assertThatClassIsImmutable(Criteria.IPDscpCriterion.class);
+ assertThatClassIsImmutable(Criteria.IPEcnCriterion.class);
assertThatClassIsImmutable(Criteria.IPProtocolCriterion.class);
assertThatClassIsImmutable(Criteria.IPCriterion.class);
assertThatClassIsImmutable(Criteria.TcpPortCriterion.class);
@@ -252,6 +277,20 @@
}
/**
+ * Test the matchInPhyPort method.
+ */
+ @Test
+ public void testMatchInPhyPortMethod() {
+ PortNumber p1 = portNumber(1);
+ Criterion matchInPhyPort = Criteria.matchInPhyPort(p1);
+ Criteria.PortCriterion portCriterion =
+ checkAndConvert(matchInPhyPort,
+ Criterion.Type.IN_PHY_PORT,
+ Criteria.PortCriterion.class);
+ assertThat(portCriterion.port(), is(equalTo(p1)));
+ }
+
+ /**
* Test the equals() method of the PortCriterion class.
*/
@Test
@@ -260,6 +299,38 @@
.addEqualityGroup(matchInPort1, sameAsMatchInPort1)
.addEqualityGroup(matchInPort2)
.testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(matchInPhyPort1, sameAsMatchInPhyPort1)
+ .addEqualityGroup(matchInPhyPort2)
+ .testEquals();
+ }
+
+ // MetadataCriterion class
+
+ /**
+ * Test the matchMetadata method.
+ */
+ @Test
+ public void testMatchMetadataMethod() {
+ Long metadata = 12L;
+ Criterion matchMetadata = Criteria.matchMetadata(metadata);
+ Criteria.MetadataCriterion metadataCriterion =
+ checkAndConvert(matchMetadata,
+ Criterion.Type.METADATA,
+ Criteria.MetadataCriterion.class);
+ assertThat(metadataCriterion.metadata(), is(equalTo(metadata)));
+ }
+
+ /**
+ * Test the equals() method of the MetadataCriterion class.
+ */
+ @Test
+ public void testMetadataCriterionEquals() {
+ new EqualsTester()
+ .addEqualityGroup(matchMetadata1, sameAsMatchMetadata1)
+ .addEqualityGroup(matchMetadata2)
+ .testEquals();
}
// EthCriterion class
@@ -380,6 +451,58 @@
.testEquals();
}
+ // IPDscpCriterion class
+
+ /**
+ * Test the matchIPDscp method.
+ */
+ @Test
+ public void testMatchIPDscpMethod() {
+ Criterion matchIPDscp = Criteria.matchIPDscp(ipDscp1);
+ Criteria.IPDscpCriterion ipDscpCriterion =
+ checkAndConvert(matchIPDscp,
+ Criterion.Type.IP_DSCP,
+ Criteria.IPDscpCriterion.class);
+ assertThat(ipDscpCriterion.ipDscp(), is(equalTo(ipDscp1)));
+ }
+
+ /**
+ * Test the equals() method of the IPDscpCriterion class.
+ */
+ @Test
+ public void testIPDscpCriterionEquals() {
+ new EqualsTester()
+ .addEqualityGroup(matchIpDscp1, sameAsMatchIpDscp1)
+ .addEqualityGroup(matchIpDscp2)
+ .testEquals();
+ }
+
+ // IPEcnCriterion class
+
+ /**
+ * Test the matchIPEcn method.
+ */
+ @Test
+ public void testMatchIPEcnMethod() {
+ Criterion matchIPEcn = Criteria.matchIPEcn(ipEcn1);
+ Criteria.IPEcnCriterion ipEcnCriterion =
+ checkAndConvert(matchIPEcn,
+ Criterion.Type.IP_ECN,
+ Criteria.IPEcnCriterion.class);
+ assertThat(ipEcnCriterion.ipEcn(), is(equalTo(ipEcn1)));
+ }
+
+ /**
+ * Test the equals() method of the IPEcnCriterion class.
+ */
+ @Test
+ public void testIPEcnCriterionEquals() {
+ new EqualsTester()
+ .addEqualityGroup(matchIpEcn1, sameAsMatchIpEcn1)
+ .addEqualityGroup(matchIpEcn2)
+ .testEquals();
+ }
+
// IpProtocolCriterion class
/**