Pavlin Radoslavov

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
......@@ -135,6 +135,16 @@ public final class DefaultTrafficSelector implements TrafficSelector {
}
@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 @@ public final class DefaultTrafficSelector implements TrafficSelector {
}
@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 final class DefaultTrafficSelector implements TrafficSelector {
public TrafficSelector build() {
return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
}
}
}
......
......@@ -68,6 +68,22 @@ public interface TrafficSelector {
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 interface TrafficSelector {
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
......
......@@ -43,7 +43,27 @@ public final class Criteria {
* @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 @@ public final class Criteria {
}
/**
* 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 final class Criteria {
*/
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 @@ public final class Criteria {
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 @@ public final class Criteria {
}
/**
* 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 {
......
......@@ -127,9 +127,12 @@ public class DefaultTrafficSelectorTest {
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 @@ public class DefaultTrafficSelectorTest {
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 @@ public class DefaultTrafficSelectorTest {
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));
......
......@@ -45,6 +45,16 @@ public class CriteriaTest {
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 @@ public class CriteriaTest {
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 @@ public class CriteriaTest {
@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 @@ public class CriteriaTest {
}
/**
* 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 @@ public class CriteriaTest {
.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 @@ public class CriteriaTest {
.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
/**
......
......@@ -355,6 +355,15 @@ public class FlowEntryBuilder {
builder.matchInPort(PortNumber
.portNumber(match.get(MatchField.IN_PORT).getPortNumber()));
break;
case IN_PHY_PORT:
builder.matchInPhyPort(PortNumber
.portNumber(match.get(MatchField.IN_PHY_PORT).getPortNumber()));
break;
case METADATA:
long metadata =
match.get(MatchField.METADATA).getValue().getValue();
builder.matchMetadata(metadata);
break;
case ETH_DST:
mac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
builder.matchEthDst(mac);
......@@ -386,6 +395,14 @@ public class FlowEntryBuilder {
byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
builder.matchVlanPcp(vlanPcp);
break;
case IP_DSCP:
byte ipDscp = match.get(MatchField.IP_DSCP).getDscpValue();
builder.matchIPDscp(ipDscp);
break;
case IP_ECN:
byte ipEcn = match.get(MatchField.IP_ECN).getEcnValue();
builder.matchIPEcn(ipEcn);
break;
case IP_PROTO:
short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
builder.matchIPProtocol((byte) proto);
......@@ -514,10 +531,6 @@ public class FlowEntryBuilder {
case ARP_SPA:
case ARP_THA:
case ARP_TPA:
case IN_PHY_PORT:
case IP_DSCP:
case IP_ECN:
case METADATA:
case MPLS_TC:
case TUNNEL_ID:
default:
......
......@@ -30,11 +30,14 @@ 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.IPDscpCriterion;
import org.onosproject.net.flow.criteria.Criteria.IPEcnCriterion;
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.MetadataCriterion;
import org.onosproject.net.flow.criteria.Criteria.PortCriterion;
import org.onosproject.net.flow.criteria.Criteria.SctpPortCriterion;
import org.onosproject.net.flow.criteria.Criteria.TcpPortCriterion;
......@@ -55,9 +58,12 @@ 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.IpDscp;
import org.projectfloodlight.openflow.types.IpEcn;
import org.projectfloodlight.openflow.types.IpProtocol;
import org.projectfloodlight.openflow.types.MacAddress;
import org.projectfloodlight.openflow.types.Masked;
import org.projectfloodlight.openflow.types.OFMetadata;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.OFVlanVidMatch;
import org.projectfloodlight.openflow.types.TransportPort;
......@@ -161,8 +167,19 @@ public abstract class FlowModBuilder {
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()));
PortCriterion inPort = (PortCriterion) c;
mBuilder.setExact(MatchField.IN_PORT,
OFPort.of((int) inPort.port().toLong()));
break;
case IN_PHY_PORT:
PortCriterion inPhyPort = (PortCriterion) c;
mBuilder.setExact(MatchField.IN_PORT,
OFPort.of((int) inPhyPort.port().toLong()));
break;
case METADATA:
MetadataCriterion metadata = (MetadataCriterion) c;
mBuilder.setExact(MatchField.METADATA,
OFMetadata.ofRaw(metadata.metadata()));
break;
case ETH_DST:
ethCriterion = (EthCriterion) c;
......@@ -193,6 +210,16 @@ public abstract class FlowModBuilder {
VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
break;
case IP_DSCP:
IPDscpCriterion ipDscpCriterion = (IPDscpCriterion) c;
mBuilder.setExact(MatchField.IP_DSCP,
IpDscp.of(ipDscpCriterion.ipDscp()));
break;
case IP_ECN:
IPEcnCriterion ipEcnCriterion = (IPEcnCriterion) c;
mBuilder.setExact(MatchField.IP_ECN,
IpEcn.of(ipEcnCriterion.ipEcn()));
break;
case IP_PROTO:
IPProtocolCriterion p = (IPProtocolCriterion) c;
mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
......@@ -353,11 +380,7 @@ public abstract class FlowModBuilder {
case ARP_SPA:
case ARP_THA:
case ARP_TPA:
case IN_PHY_PORT:
case IPV6_EXTHDR:
case IP_DSCP:
case IP_ECN:
case METADATA:
case MPLS_BOS:
case MPLS_TC:
case PBB_ISID:
......
......@@ -43,10 +43,17 @@ public final class CriterionCodec extends JsonCodec<Criterion> {
switch (criterion.type()) {
case IN_PORT:
case IN_PHY_PORT:
final Criteria.PortCriterion portCriterion = (Criteria.PortCriterion) criterion;
result.put("port", portCriterion.port().toLong());
break;
case METADATA:
final Criteria.MetadataCriterion metadataCriterion =
(Criteria.MetadataCriterion) criterion;
result.put("metadata", metadataCriterion.metadata());
break;
case ETH_DST:
case ETH_SRC:
final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
......@@ -71,6 +78,18 @@ public final class CriterionCodec extends JsonCodec<Criterion> {
result.put("priority", vlanPcpCriterion.priority());
break;
case IP_DSCP:
final Criteria.IPDscpCriterion ipDscpCriterion =
(Criteria.IPDscpCriterion) criterion;
result.put("ipDscp", ipDscpCriterion.ipDscp());
break;
case IP_ECN:
final Criteria.IPEcnCriterion ipEcnCriterion =
(Criteria.IPEcnCriterion) criterion;
result.put("ipEcn", ipEcnCriterion.ipEcn());
break;
case IP_PROTO:
final Criteria.IPProtocolCriterion iPProtocolCriterion =
(Criteria.IPProtocolCriterion) criterion;
......
......@@ -35,7 +35,8 @@ public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNo
// CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES
@Override
public boolean matchesSafely(JsonNode jsonCriterion, Description description) {
public boolean matchesSafely(JsonNode jsonCriterion,
Description description) {
final String type = criterion.type().name();
final String jsonType = jsonCriterion.get("type").asText();
if (!type.equals(jsonType)) {
......@@ -46,7 +47,9 @@ public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNo
switch (criterion.type()) {
case IN_PORT:
final Criteria.PortCriterion portCriterion = (Criteria.PortCriterion) criterion;
case IN_PHY_PORT:
final Criteria.PortCriterion portCriterion =
(Criteria.PortCriterion) criterion;
final long port = portCriterion.port().toLong();
final long jsonPort = jsonCriterion.get("port").asLong();
if (port != jsonPort) {
......@@ -55,9 +58,21 @@ public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNo
}
break;
case METADATA:
final Criteria.MetadataCriterion metadataCriterion =
(Criteria.MetadataCriterion) criterion;
final long metadata = metadataCriterion.metadata();
final long jsonMetadata = jsonCriterion.get("metadata").asLong();
if (metadata != jsonMetadata) {
description.appendText("metadata was " + Long.toString(jsonMetadata));
return false;
}
break;
case ETH_DST:
case ETH_SRC:
final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
final Criteria.EthCriterion ethCriterion =
(Criteria.EthCriterion) criterion;
final String mac = ethCriterion.mac().toString();
final String jsonMac = jsonCriterion.get("mac").textValue();
if (!mac.equals(jsonMac)) {
......@@ -99,6 +114,28 @@ public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNo
}
break;
case IP_DSCP:
final Criteria.IPDscpCriterion ipDscpCriterion =
(Criteria.IPDscpCriterion) criterion;
final byte ipDscp = ipDscpCriterion.ipDscp();
final byte jsonIpDscp = (byte) jsonCriterion.get("ipDscp").shortValue();
if (ipDscp != jsonIpDscp) {
description.appendText("IP DSCP was " + Byte.toString(jsonIpDscp));
return false;
}
break;
case IP_ECN:
final Criteria.IPEcnCriterion ipEcnCriterion =
(Criteria.IPEcnCriterion) criterion;
final byte ipEcn = ipEcnCriterion.ipEcn();
final byte jsonIpEcn = (byte) jsonCriterion.get("ipEcn").shortValue();
if (ipEcn != jsonIpEcn) {
description.appendText("IP ECN was " + Byte.toString(jsonIpEcn));
return false;
}
break;
case IP_PROTO:
final Criteria.IPProtocolCriterion iPProtocolCriterion =
(Criteria.IPProtocolCriterion) criterion;
......@@ -114,7 +151,8 @@ public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNo
case IPV4_DST:
case IPV6_SRC:
case IPV6_DST:
final Criteria.IPCriterion ipCriterion = (Criteria.IPCriterion) criterion;
final Criteria.IPCriterion ipCriterion =
(Criteria.IPCriterion) criterion;
final String ip = ipCriterion.ip().toString();
final String jsonIp = jsonCriterion.get("ip").textValue();
if (!ip.equals(jsonIp)) {
......@@ -217,7 +255,7 @@ public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNo
case IPV6_ND_TARGET:
final Criteria.IPv6NDTargetAddressCriterion
ipv6NDTargetAddressCriterion =
(Criteria.IPv6NDTargetAddressCriterion) criterion;
(Criteria.IPv6NDTargetAddressCriterion) criterion;
final String targetAddress =
ipv6NDTargetAddressCriterion.targetAddress().toString();
final String jsonTargetAddress =
......@@ -233,7 +271,7 @@ public final class CriterionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNo
case IPV6_ND_TLL:
final Criteria.IPv6NDLinkLayerAddressCriterion
ipv6NDLinkLayerAddressCriterion =
(Criteria.IPv6NDLinkLayerAddressCriterion) criterion;
(Criteria.IPv6NDLinkLayerAddressCriterion) criterion;
final String llAddress =
ipv6NDLinkLayerAddressCriterion.mac().toString();
final String jsonLlAddress =
......