From 4a69ef82e252493318b13cd1bfab0fe63d30be67 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Tue, 21 Aug 2018 21:18:05 -0700 Subject: [PATCH] TrafficTreatment: add support for IP DSCP modifications Allow modifying IP DSCP field in the headers. Change-Id: Idd765f40f1baec810273536adcd56bf0e480217f --- .../net/flow/DefaultTrafficTreatment.java | 5 ++ .../net/flow/TrafficTreatment.java | 8 +++ .../net/flow/instructions/Instructions.java | 10 ++++ .../L3ModificationInstruction.java | 53 ++++++++++++++++++- .../of/flow/impl/FlowModBuilderVer13.java | 6 +++ .../of/flow/util/FlowEntryBuilder.java | 7 ++- 6 files changed, 87 insertions(+), 2 deletions(-) diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java index c6a1c169ce..72cfd3f6e3 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java +++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java @@ -514,6 +514,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { return add(Instructions.piTableAction(piTableAction)); } + @Override + public TrafficTreatment.Builder setIpDscp(byte dscpValue) { + return add(Instructions.modIpDscp(dscpValue)); + } + @Override public TrafficTreatment.Builder extension(ExtensionTreatment extension, DeviceId deviceId) { diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java index f61b017ebb..154f8c603a 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java +++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java @@ -427,6 +427,14 @@ public interface TrafficTreatment { @Beta Builder piTableAction(PiTableAction piTableAction); + /** + * Sets the IP DSCP field. + * + * @param dscpValue the DSCP value + * @return a treatment builder. + */ + Builder setIpDscp(byte dscpValue); + /** * Uses an extension treatment. * diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java index 33b74829da..e0c58d338a 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java +++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java @@ -484,6 +484,16 @@ public final class Instructions { return new PiInstruction(piTableAction); } + /** + * Creates an IP DSCP modification. + * + * @param dscpValue the DSCP value to modify to + * @return a L3 modification + */ + public static Instruction modIpDscp(byte dscpValue) { + return new L3ModificationInstruction.ModDscpInstruction(L3SubType.IP_DSCP, dscpValue); + } + /** * Creates an extension instruction. * diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java index 9fddf89b19..cc15360109 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java +++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java @@ -84,7 +84,12 @@ public abstract class L3ModificationInstruction implements Instruction { /** * Arp operation modification. */ - ARP_OP + ARP_OP, + + /** + * IP DSCP operation modification. + */ + IP_DSCP } /** @@ -380,4 +385,50 @@ public abstract class L3ModificationInstruction implements Instruction { return false; } } + + /** + * Represents a L3 DSCP modification instruction. + */ + public static final class ModDscpInstruction extends L3ModificationInstruction { + + private final L3SubType subtype; + private final byte dscp; + + ModDscpInstruction(L3SubType subtype, byte dscp) { + this.subtype = subtype; + this.dscp = dscp; + } + + @Override + public L3SubType subtype() { + return this.subtype; + } + + @Override + public String toString() { + return subtype().toString() + SEPARATOR + dscp(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), dscp()); + } + + public byte dscp() { + return this.dscp; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModDscpInstruction) { + ModDscpInstruction that = (ModDscpInstruction) obj; + return Objects.equals(this.subtype(), that.subtype()) && + Objects.equals(this.dscp(), that.dscp()); + } + return false; + } + } } diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java index ad601c98cc..abc2e604f4 100644 --- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java +++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java @@ -75,6 +75,7 @@ import org.projectfloodlight.openflow.types.EthType; 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.MacAddress; import org.projectfloodlight.openflow.types.OFBooleanValue; import org.projectfloodlight.openflow.types.OFBufferId; @@ -447,6 +448,11 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ip4 = ip.ip().getIp4Address(); oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt())); break; + case IP_DSCP: + L3ModificationInstruction.ModDscpInstruction dscp = (L3ModificationInstruction.ModDscpInstruction) i; + IpDscp ipDscp = IpDscp.of(dscp.dscp()); + oxm = factory().oxms().ipDscp(ipDscp); + break; case IPV6_SRC: ip = (ModIPInstruction) i; ip6 = ip.ip().getIp6Address(); 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 9885574bd4..a32466f35f 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 @@ -94,6 +94,7 @@ import org.projectfloodlight.openflow.protocol.ver13.OFFactoryVer13; import org.projectfloodlight.openflow.types.CircuitSignalID; import org.projectfloodlight.openflow.types.IPv4Address; import org.projectfloodlight.openflow.types.IPv6Address; +import org.projectfloodlight.openflow.types.IpDscp; import org.projectfloodlight.openflow.types.Masked; import org.projectfloodlight.openflow.types.OFBooleanValue; import org.projectfloodlight.openflow.types.OFVlanVidMatch; @@ -809,6 +810,11 @@ public class FlowEntryBuilder { } } break; + case IP_DSCP: + @SuppressWarnings("unchecked") + OFOxm ipDscp = (OFOxm) oxm; + builder.setIpDscp(ipDscp.getValue().getDscpValue()); + break; case ARP_THA: case ARP_TPA: case BSN_EGR_PORT_GROUP_ID: @@ -842,7 +848,6 @@ public class FlowEntryBuilder { case IPV6_ND_TARGET: case IPV6_ND_TLL: case IPV6_SRC: - case IP_DSCP: case IP_ECN: case IP_PROTO: case METADATA: