Introducing BandwidthProfileConfigBehaviour to manage policers/markers
- Creating BandwidthProfile Class to represent generic policers/markers
- BandwidthProfile can be Single/Two Rate, Two/Three Color depending on parameters
- Including fromMeter() method to convert a Meter into a BandwidthProfile
- Adding unit tests for BandwidthProfile class
- Creating BandwidthProfileAction class to represent a color (green/yellow/red) action
- BandwidthProfileAction allows remarking one of: DSCP class, IP precedence, Drop precedence
- Adding unit tests for BandwidthProfileAction class
- Creating DscpClass and IPPrecedence Enums and unit tests in org.onlab.packet
- Adding kBps/MBps/GBps methods in org.onlab.util.Bandwidth class
Change-Id: I54156329a527ebd9165d8f55e03e0782925caa2b
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfile.java b/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfile.java
new file mode 100644
index 0000000..2a934fd
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfile.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.behaviour;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.DscpClass;
+import org.onlab.util.Bandwidth;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.Meter;
+import static org.onosproject.net.behaviour.BandwidthProfileAction.Action;
+
+import java.util.Iterator;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of a generic bandwidth profile (marker/policer).
+ */
+@Beta
+public final class BandwidthProfile {
+
+ /**
+ * Denotes the type of the bandwidth profile.
+ */
+ enum Type {
+ /**
+ * Corresponds to a Single Rate Two Color Marker/Policer.
+ */
+ sr2CM,
+
+ /**
+ * Corresponds to a Single Rate Three Color Marker/Policer.
+ * (IETF RFC 2697)
+ */
+ srTCM,
+
+ /**
+ * Corresponds to a Two Rate Three Color Marker/Policer.
+ * (IETF RFC 2698)
+ */
+ trTCM
+ }
+
+ private final String name;
+ private final Bandwidth cir;
+ private final Bandwidth pir;
+ private final Integer cbs;
+ private final Integer pbs;
+ private final Integer ebs;
+ private final BandwidthProfileAction greenAction;
+ private final BandwidthProfileAction yellowAction;
+ private final BandwidthProfileAction redAction;
+ private final boolean colorAware;
+
+ /**
+ * BandwidthProfile constructor.
+ *
+ * @param name the profile name
+ * @param cir the committed information rate (CIR)
+ * @param cbs the committed burst size (CBS) measured in bytes
+ * @param pir the peak information rate (PIR)
+ * @param pbs the peak burst size (PBS) measured in bytes
+ * @param greenAction the action to be taken for traffic that conforms
+ * to the CIR/CBS
+ * @param yellowAction srTCM: the action to be taken for traffic that
+ * conforms to the EBS but not to the CIR/CBS
+ * trTCM: the action to be taken for traffic that
+ * conforms to the PIR/PBS but not to the CIR/CBS
+ * @param redAction sr2CM: the action to be taken for traffic that
+ * does not conform to the CIR/CBS
+ * srTCM: the action to be taken for traffic that
+ * does not conform to the EBS
+ * trTCM: the action to be taken for traffic that
+ * does not conform to the PIR/PBS
+ * @param colorAware indicates whether the profile considers incoming
+ * traffic as already colored
+ */
+ private BandwidthProfile(String name,
+ Bandwidth cir, Bandwidth pir,
+ Integer cbs, Integer pbs, Integer ebs,
+ BandwidthProfileAction greenAction,
+ BandwidthProfileAction yellowAction,
+ BandwidthProfileAction redAction,
+ boolean colorAware) {
+ this.name = name;
+ this.cir = cir;
+ this.pir = pir;
+ this.cbs = cbs;
+ this.pbs = pbs;
+ this.ebs = ebs;
+ this.greenAction = greenAction;
+ this.yellowAction = yellowAction;
+ this.redAction = redAction;
+ this.colorAware = colorAware;
+ }
+
+ /**
+ * Obtains the name of this bandwidth profile.
+ *
+ * @return the bandwidth profile name
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Obtains the committed information rate (CIR) of this bandwidth profile.
+ *
+ * @return the CIR of the bandwidth profile
+ */
+ public Bandwidth cir() {
+ return cir;
+ }
+
+ /**
+ * Obtains the peak information rate (PIR) of this bandwidth profile.
+ * If this profile does not have a PIR, null is returned.
+ *
+ * @return the PIR of the profile; null if the profile does not have a PIR
+ */
+ public Bandwidth pir() {
+ return pir;
+ }
+
+ /**
+ * Obtains the committed burst size (CBS) of this bandwidth profile.
+ * The CBS is measured in bytes.
+ * If this profile does not have a CBS, null is returned.
+ *
+ * @return the CBS of the profile (bytes);
+ * null if the profile does not have a CBS
+ */
+ public Integer cbs() {
+ return cbs;
+ }
+
+ /**
+ * Obtains the peak burst size (PBS) of this bandwidth profile.
+ * The PBS is measured in bytes.
+ * If this profile does not have a PBS, null is returned.
+ *
+ * @return the PBS of the bandwidth profile (bytes);
+ * null if the profile does not have a PBS
+ */
+ public Integer pbs() {
+ return pbs;
+ }
+
+ /**
+ * Obtains the excess burst size (EBS) of this bandwidth profile.
+ * The EBS is measured in bytes.
+ * If this profile does not have an EBS, null is returned.
+ *
+ * @return the EBS of the bandwidth profile (bytes);
+ * null if the profile does not have an EBS
+ */
+ public Integer ebs() {
+ return ebs;
+ }
+
+ /**
+ * Obtains the action to be taken for traffic marked as green.
+ * Green color marking is applied to traffic that conforms to the CIR/CBS.
+ *
+ * @return the action to be taken for traffic marked as green
+ */
+ public BandwidthProfileAction greenAction() {
+ return greenAction;
+ }
+
+ /**
+ * Obtains the action to be taken for traffic marked as yellow.
+ * Yellow color marking is applied to traffic that does not conform
+ * to the CIR/CBS but conforms to one of:
+ * <ul>
+ * <li>EBS (srTCM type)</li>
+ * <li>PIR/PBS (trTCM type)</li>
+ * </ul>
+ * If this profile does has neither EBS or PIR/PBS, null is returned.
+ *
+ * @return the action to be taken for traffic marked as yellow;
+ * null if neither EBS nor PIR/PBS are defined
+ */
+ public BandwidthProfileAction yellowAction() {
+ return yellowAction;
+ }
+
+ /**
+ * Obtains the action to be taken for traffic marked as red.
+ * Red color marking is applied to traffic that does not conform
+ * to one of the following:
+ * <ul>
+ * <li>CIR/CBS (sr2CM type)</li>
+ * <li>EBS (srTCM type)</li>
+ * <li>PIR/PBS (trTCM type)</li>
+ * </ul>
+ *
+ * @return the action to be taken for traffic marked as red
+ */
+ public BandwidthProfileAction redAction() {
+ return redAction;
+ }
+
+ /**
+ * Obtains the color-aware mode of the bandwidth profile.
+ *
+ * @return true if the bandwidth profile is color-aware; false otherwise
+ */
+ public boolean colorAware() {
+ return colorAware;
+ }
+
+ /**
+ * Obtains the bandwidth profile type depending on the profile parameters.
+ * <ul>
+ * <li>When PIR is defined, the profile corresponds to a
+ * Two Rate Three Color Marker (trTCM)</li>
+ * <li>When EBS is defined, the profile corresponds to a
+ * Single Rate Three Color Marker (srTCM)</li>
+ * <li>When neither PIR nor EBS are defined, the profile corresponds to a
+ * Single Rate Two Color Marker/Policer (sr2CM)</li>
+ * </ul>
+ *
+ * @return the bandwidth profile type
+ */
+ public Type type() {
+ return pir != null ? Type.trTCM :
+ ebs != null ? Type.srTCM : Type.sr2CM;
+ }
+
+ /**
+ * Creates a bandwidth profile based on the parameters of a Meter.
+ * NOTE: The dropPrecedence in the Meter is interpreted as
+ * the DSCP class to set on the packet
+ *
+ * @param meter the Meter to be used for creating the bandwidth profile
+ * @return the bandwidth profile created
+ */
+ public static BandwidthProfile fromMeter(Meter meter) {
+
+ checkNotNull(meter);
+ checkArgument(meter.bands().size() <= 2,
+ "Meter must have no more than two bands.");
+
+ Iterator<Band> bandIterator = meter.bands().iterator();
+ Band bandOne = bandIterator.next();
+ Band bandTwo = bandIterator.hasNext() ? bandIterator.next() : null;
+
+ // Assign values to yellowBand and redBand depending on
+ // the number of bands in the meter.
+ // If only one band exists it will be designated as the redBand.
+ // If two bands exist, the one with the lower rate will be
+ // the yellowBand and the other the redBand.
+ Band yellowBand = (bandTwo == null ? null :
+ bandTwo.rate() > bandOne.rate() ? bandOne : bandTwo);
+ Band redBand = (bandTwo == null ? bandOne :
+ yellowBand == bandOne ? bandTwo : bandOne);
+
+ BandwidthProfile.Builder bandwidthProfileBuilder = new Builder()
+ // Consider the meter id as the bandwidth profile name
+ .name(meter.id().toString())
+ .colorAware(false)
+ // The implicit green action is pass
+ .greenAction(getBuilder(Action.PASS).build());
+
+ if (yellowBand != null) {
+ // Try to add yellow action; CIR/CBS will be obtained from
+ // yellowBand and PIR/PBS from redBand.
+ BandwidthProfileAction yellowAction =
+ getBwProfileActionFromBand(yellowBand);
+ checkNotNull(yellowAction,
+ "Could not obtain yellow action from meter band");
+ bandwidthProfileBuilder
+ .cir(Bandwidth.kBps(yellowBand.rate()))
+ .cbs(yellowBand.burst() == null ? null :
+ yellowBand.burst().intValue())
+ .pir(Bandwidth.kBps(redBand.rate()))
+ .pbs(redBand.burst() == null ? null :
+ redBand.burst().intValue())
+ .yellowAction(yellowAction);
+ } else {
+ // No yellow action to add; CIR/CBS will be obtained from redBand
+ bandwidthProfileBuilder
+ .cir(Bandwidth.kBps(redBand.rate()))
+ .cbs(redBand.burst() == null ? null :
+ redBand.burst().intValue());
+ }
+
+ // Try to add red action in any case
+ BandwidthProfileAction redAction =
+ getBwProfileActionFromBand(redBand);
+ checkNotNull(redAction,
+ "Could not obtain red action from meter band");
+
+ return bandwidthProfileBuilder
+ .redAction(redAction)
+ .build();
+ }
+
+ private static BandwidthProfileAction.Builder getBuilder(Action action) {
+ return BandwidthProfileAction.builder().action(action);
+ }
+
+ private static BandwidthProfileAction getBwProfileActionFromBand(Band band) {
+ checkNotNull(band.type(),
+ "Could not obtain BW profile: Meter band type is null");
+ Action action = null;
+ if (band.type().equals(Band.Type.DROP)) {
+ action = Action.DISCARD;
+ } else if (band.type().equals(Band.Type.REMARK)) {
+ action = Action.REMARK;
+ }
+ checkNotNull(action,
+ "Could not obtain BW profile: Invalid meter band type");
+ BandwidthProfileAction.Builder actionBuilder = getBuilder(action);
+ if (band.type().equals(Band.Type.REMARK)) {
+ checkNotNull(band.dropPrecedence(),
+ "Could not obtain DSCP class from meter band");
+ actionBuilder.dscpClass(DscpClass.fromShort(band.dropPrecedence()));
+ }
+ return actionBuilder.build();
+ }
+
+ /**
+ * Returns a new builder.
+ *
+ * @return new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder of BandwidthProfile entities.
+ */
+ public static final class Builder {
+
+ private String name;
+ private Bandwidth cir;
+ private Bandwidth pir;
+ private Integer cbs;
+ private Integer pbs;
+ private Integer ebs;
+ private BandwidthProfileAction greenAction;
+ private BandwidthProfileAction yellowAction;
+ private BandwidthProfileAction redAction;
+ private boolean colorAware;
+
+ /**
+ * Sets the name of this bandwidth profile builder.
+ *
+ * @param name the builder name to set
+ * @return this builder instance
+ */
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ /**
+ * Sets the committed information rate (CIR) of this builder.
+ *
+ * @param cir the builder CIR to set
+ * @return this builder instance
+ */
+ public Builder cir(Bandwidth cir) {
+ this.cir = cir;
+ return this;
+ }
+
+ /**
+ * Sets the peak information rate (PIR) of this builder.
+ *
+ * @param pir the builder PIR to set
+ * @return this builder instance
+ */
+ public Builder pir(Bandwidth pir) {
+ this.pir = pir;
+ return this;
+ }
+
+ /**
+ * Sets the committed burst size (CBS) of this builder.
+ * The CBS is measured in bytes.
+ *
+ * @param cbs the builder CBS to set
+ * @return this builder instance
+ */
+ public Builder cbs(Integer cbs) {
+ this.cbs = cbs;
+ return this;
+ }
+
+ /**
+ * Sets the peak burst size (PBS) of this builder.
+ * The PBS is measured in bytes.
+ *
+ * @param pbs the builder CBS to set
+ * @return this builder instance
+ */
+ public Builder pbs(Integer pbs) {
+ this.pbs = pbs;
+ return this;
+ }
+
+ /**
+ * Sets the excess burst size (EBS) of this builder.
+ * The EBS is measured in bytes.
+ *
+ * @param ebs the builder EBS to set
+ * @return this builder instance
+ */
+ public Builder ebs(Integer ebs) {
+ this.ebs = ebs;
+ return this;
+ }
+
+ /**
+ * Sets the green action of this builder.
+ *
+ * @param greenAction the builder green action to set
+ * @return this builder instance
+ */
+ public Builder greenAction(BandwidthProfileAction greenAction) {
+ this.greenAction = greenAction;
+ return this;
+ }
+
+ /**
+ * Sets the yellow action of this builder.
+ *
+ * @param yellowAction the builder green action to set
+ * @return this builder instance
+ */
+ public Builder yellowAction(BandwidthProfileAction yellowAction) {
+ this.yellowAction = yellowAction;
+ return this;
+ }
+
+ /**
+ * Sets the red action of this builder.
+ *
+ * @param redAction the builder green action to set
+ * @return this builder instance
+ */
+ public Builder redAction(BandwidthProfileAction redAction) {
+ this.redAction = redAction;
+ return this;
+ }
+
+ /**
+ * Sets the color-aware mode of this builder.
+ *
+ * @param colorAware true if profile to be build is color-aware;
+ * false otherwise
+ * @return this builder instance
+ */
+ public Builder colorAware(boolean colorAware) {
+ this.colorAware = colorAware;
+ return this;
+ }
+
+ /**
+ * Builds a new BandwidthProfile instance.
+ * based on this builder's parameters
+ *
+ * @return a new BandwidthProfile instance
+ */
+ public BandwidthProfile build() {
+ checkNotNull(name, "Bandwidth profile must have a name");
+ checkNotNull(cir, "Bandwidth profile must have a CIR");
+ checkNotNull(greenAction,
+ "Bandwidth profile must have a green action");
+ checkNotNull(redAction,
+ "Bandwidth profile must have a red action");
+ checkArgument(pir != null || pbs == null,
+ "Bandwidth profile cannot have PBS without PIR");
+ checkArgument(pir == null || ebs == null,
+ "Bandwidth profile cannot have both PIR and EBS");
+ checkArgument(yellowAction == null && pir == null && ebs == null ||
+ yellowAction != null &&
+ (pir != null ^ ebs != null),
+ "Bandwidth profile must have a yellow action only " +
+ "when either PIR or EBS are defined");
+ return new BandwidthProfile(name,
+ cir, pir, cbs, pbs, ebs,
+ greenAction, yellowAction, redAction,
+ colorAware);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(cir, pir, cbs, pbs, ebs,
+ greenAction, yellowAction, redAction,
+ colorAware);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof BandwidthProfile) {
+ final BandwidthProfile that = (BandwidthProfile) obj;
+ return this.getClass() == that.getClass() &&
+ Objects.equals(this.cir, that.cir) &&
+ Objects.equals(this.pir, that.pir) &&
+ Objects.equals(this.cbs, that.cbs) &&
+ Objects.equals(this.pbs, that.pbs) &&
+ Objects.equals(this.ebs, that.ebs) &&
+ Objects.equals(this.greenAction, that.greenAction) &&
+ Objects.equals(this.yellowAction, that.yellowAction) &&
+ Objects.equals(this.redAction, that.redAction) &&
+ Objects.equals(this.colorAware, that.colorAware);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("name", name)
+ .add("cir", cir)
+ .add("pir", pir)
+ .add("cbs", cbs)
+ .add("pbs", pbs)
+ .add("ebs", ebs)
+ .add("greenAction", greenAction)
+ .add("yellowAction", yellowAction)
+ .add("redAction", redAction)
+ .add("colorAware", colorAware)
+ .toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfileAction.java b/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfileAction.java
new file mode 100644
index 0000000..ae6a153
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfileAction.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.behaviour;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.DscpClass;
+import org.onlab.packet.IPPrecedence;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * Represents an action to be taken by a marker/policer.
+ */
+@Beta
+public final class BandwidthProfileAction {
+
+ /**
+ * Denotes the type of action to be taken.
+ */
+ public enum Action {
+ /**
+ * Traffic is allowed to pass unmodified.
+ */
+ PASS,
+
+ /**
+ * Traffic is allowed to pass after being appropriately remarked.
+ */
+ REMARK,
+
+ /**
+ * Traffic is dropped.
+ */
+ DISCARD
+ }
+
+ private final Action action;
+ private final DscpClass dscpClass;
+ private final IPPrecedence ipPrecedence;
+ private final Short dropPrecedence;
+
+ private BandwidthProfileAction(Action action,
+ DscpClass dscpClass,
+ IPPrecedence ipPrecedence,
+ Short dropPrecedence) {
+ this.action = action;
+ this.dscpClass = dscpClass;
+ this.ipPrecedence = ipPrecedence;
+ this.dropPrecedence = dropPrecedence;
+ }
+
+ /**
+ * Obtains the type of this bandwidth profile action object.
+ *
+ * @return the bandwidth profile action type
+ */
+ public Action getAction() {
+ return this.action;
+ }
+
+ /**
+ * Obtains the DSCP class corresponding to the REMARK action.
+ * If this is not a REMARK action or if another field is remarked
+ * null is returned.
+ *
+ * @return the DSCP class for the action; may be null
+ */
+ public DscpClass getDscpClass() {
+ return this.dscpClass;
+ }
+
+ /**
+ * Obtains the IP precedence corresponding to the REMARK action.
+ * If this is not a REMARK action or if another field is remarked
+ * null is returned.
+ *
+ * @return the IP precedence for the action; may be null
+ */
+ public IPPrecedence getIpPrecedence() {
+ return this.ipPrecedence;
+ }
+
+ /**
+ * Obtains the drop precedence corresponding to the REMARK action.
+ * If this is not a REMARK action or if another field is remarked
+ * null is returned.
+ *
+ * @return the drop precedence for the action; may be null
+ */
+ public Short getDropPrecedence() {
+ return this.dropPrecedence;
+ }
+
+ /**
+ * Returns a new builder.
+ *
+ * @return new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder of BandwidthProfileAction entities.
+ */
+ public static final class Builder {
+
+ private Action action;
+ private DscpClass dscpClass;
+ private IPPrecedence ipPrecedence;
+ private Short dropPrecedence;
+
+ /**
+ * Sets the type of this builder.
+ *
+ * @param action the builder type to set
+ * @return this builder instance
+ */
+ public Builder action(Action action) {
+ this.action = action;
+ return this;
+ }
+
+ /**
+ * Sets the DSCP class of this builder.
+ *
+ * @param dscpClass the builder DSCP class to set
+ * @return this builder instance
+ */
+ public Builder dscpClass(DscpClass dscpClass) {
+ this.dscpClass = dscpClass;
+ return this;
+ }
+
+ /**
+ * Sets the IP precedence of this builder.
+ *
+ * @param ipPrecedence the builder IP precedence to set
+ * @return this builder instance
+ */
+ public Builder ipPrecedence(IPPrecedence ipPrecedence) {
+ this.ipPrecedence = ipPrecedence;
+ return this;
+ }
+
+ /**
+ * Sets the drop precedence of this builder.
+ *
+ * @param dropPrecedence the drop IP precedence to set
+ * @return this builder instance
+ */
+ public Builder dropPrecedence(Short dropPrecedence) {
+ this.dropPrecedence = dropPrecedence;
+ return this;
+ }
+
+ /**
+ * Builds a new BandwidthProfileAction based on builder's parameters.
+ *
+ * @return a new BandwidthProfileAction instance
+ */
+ public BandwidthProfileAction build() {
+ checkNotNull(action);
+ checkArgument(!action.equals(Action.REMARK) ||
+ (dscpClass != null ^
+ ipPrecedence != null ^
+ dropPrecedence != null),
+ "Exactly one remark type must be defined");
+ return new BandwidthProfileAction(action,
+ dscpClass,
+ ipPrecedence,
+ dropPrecedence);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(action, dscpClass, ipPrecedence, dropPrecedence);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof BandwidthProfileAction) {
+ final BandwidthProfileAction that = (BandwidthProfileAction) obj;
+ return this.getClass() == that.getClass() &&
+ Objects.equals(this.action, that.action) &&
+ Objects.equals(this.dscpClass, that.dscpClass) &&
+ Objects.equals(this.ipPrecedence, that.ipPrecedence) &&
+ Objects.equals(this.dropPrecedence, that.dropPrecedence);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("action", action == null ? null : action.name())
+ .add("dscpClass", dscpClass == null ? null : dscpClass.name())
+ .add("ipPrecedence", ipPrecedence)
+ .add("dropPrecedence", dropPrecedence)
+ .toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfileConfigBehaviour.java b/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfileConfigBehaviour.java
new file mode 100644
index 0000000..bd222cd
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/BandwidthProfileConfigBehaviour.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.behaviour;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.HandlerBehaviour;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Collection;
+
+/**
+ * Means to configure bandwidth profiles on devices.
+ */
+@Beta
+public interface BandwidthProfileConfigBehaviour extends HandlerBehaviour {
+ /**
+ * Adds a new bandwidth profile on the device.
+ * If a profile with the same name already exists on the device, the profile
+ * is not added.
+ *
+ * @param bwProfile the bandwidth profile to add
+ * @return true, if the profile was added successfully; false otherwise
+ */
+ default boolean addBandwidthProfile(BandwidthProfile bwProfile) {
+ return addBandwidthProfile(Collections.singletonList(bwProfile));
+ }
+
+ /**
+ * Adds new bandwidth profiles on the device.
+ * If profiles with the same names already exist on the device, the
+ * conflicting profiles are not added.
+ *
+ * @param bwProfiles the bandwidth profiles to add
+ * @return true, if any of the profiles were added successfully;
+ * false otherwise
+ */
+ boolean addBandwidthProfile(Collection<BandwidthProfile> bwProfiles);
+
+ /**
+ * Removes an existing bandwidth profile from a device.
+ * Returns false if the profile does not exist on the device.
+ *
+ * @param profileName the name of the profile to remove from the device
+ * @return true, if the profile was removed successfully; false otherwise
+ */
+ default boolean removeBandwidthProfile(String profileName) {
+ return removeBandwidthProfile(Collections.singletonList(profileName));
+ }
+
+ /**
+ * Removes existing bandwidth profiles from a device.
+ * Returns false if none of the profiles exist on the device.
+ *
+ * @param profileNames the names of the profiles to remove from the device
+ * @return true, if any of the profiles were removed successfully;
+ * false otherwise
+ */
+ boolean removeBandwidthProfile(Collection<String> profileNames);
+
+ /**
+ * Removes all existing bandwidth profiles from a device.
+ * Returns true if no profiles exist on the device.
+ *
+ * @return true, if all profiles were removed successfully; false otherwise
+ */
+ boolean removeAllBandwidthProfiles();
+
+ /**
+ * Updates an already configured bandwidth profile on the device.
+ * Returns false if the profile does not exist on the device.
+ *
+ * @param bwProfile the updated bandwidth profile
+ * @return true, if the profile was updated successfully; false otherwise
+ */
+ default boolean updateBandwidthProfile(BandwidthProfile bwProfile) {
+ return updateBandwidthProfile(Collections.singletonList(bwProfile));
+ }
+
+ /**
+ * Updates already configured bandwidth profiles on the device.
+ * Returns false if none of the profiles exist on the device.
+ *
+ * @param bwProfiles the updated bandwidth profile
+ * @return true, if any of the profiles were updated successfully;
+ * false otherwise
+ */
+ boolean updateBandwidthProfile(
+ Collection<BandwidthProfile> bwProfiles);
+
+ /**
+ * Obtains an already configured bandwidth profile from the device.
+ *
+ * @param profileName the name of the profile to obtain from the device
+ * @return the bandwidth profile; null if the profile does not exist
+ * @throws IOException if profile could not be obtained due to
+ * communication issues with the device
+ */
+ BandwidthProfile getBandwidthProfile(String profileName) throws IOException;
+
+ /**
+ * Obtains all already configured bandwidth profiles from the device.
+ *
+ * @return the bandwidth profiles; empty collection if no profiles exist
+ * @throws IOException if profiles could not be obtained due to
+ * communication issues with the device
+ */
+ Collection<BandwidthProfile> getAllBandwidthProfiles() throws IOException;
+}
diff --git a/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileActionTest.java b/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileActionTest.java
new file mode 100644
index 0000000..e8bc68c
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileActionTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.behaviour;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onlab.packet.DscpClass;
+import static org.onosproject.net.behaviour.BandwidthProfileAction.Action;
+
+/**
+ * Test for BandwidthProfileAction class.
+ */
+public class BandwidthProfileActionTest {
+
+ @Test
+ public void testEquals() {
+ BandwidthProfileAction passAction1 = BandwidthProfileAction.builder()
+ .action(Action.PASS)
+ .build();
+ BandwidthProfileAction passAction2 = BandwidthProfileAction.builder()
+ .action(Action.PASS)
+ .build();
+ BandwidthProfileAction discardAction1 = BandwidthProfileAction.builder()
+ .action(Action.DISCARD)
+ .build();
+ BandwidthProfileAction discardAction2 = BandwidthProfileAction.builder()
+ .action(Action.DISCARD)
+ .build();
+ BandwidthProfileAction remarkAction1 = BandwidthProfileAction.builder()
+ .action(Action.REMARK)
+ .dscpClass(DscpClass.AF11)
+ .build();
+ BandwidthProfileAction remarkAction2 = BandwidthProfileAction.builder()
+ .action(Action.REMARK)
+ .dscpClass(DscpClass.AF11)
+ .build();
+ new EqualsTester()
+ .addEqualityGroup(passAction1, passAction2)
+ .addEqualityGroup(discardAction1, discardAction2)
+ .addEqualityGroup(remarkAction1, remarkAction2)
+ .testEquals();
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileTest.java b/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileTest.java
new file mode 100644
index 0000000..8052593
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.behaviour;
+
+import org.junit.Test;
+import org.onlab.packet.DscpClass;
+import org.onlab.util.Bandwidth;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.DefaultMeter;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterId;
+import static org.onosproject.net.behaviour.BandwidthProfileAction.Action;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test for BandwidthProfile class.
+ */
+public class BandwidthProfileTest {
+
+ private static final long ONE = 1L;
+ private static final long ONE_K = 1_000L;
+ private static final long TWO_K = 2_000L;
+ private static final long EIGHT_K = 8_000L;
+ private static final long ONE_M = 1_000_000L;
+ private static final long TEN_M = 10_000_000L;
+
+ @Test
+ public void testMeterConversion() {
+ DeviceId deviceId = DeviceId.deviceId("netconf:10.0.0.1:22");
+ ApplicationId appId = TestApplicationId.create("org.onosproject.foo.app");
+ Meter.Builder meterBuilder = new DefaultMeter.Builder()
+ .withId(MeterId.meterId(ONE))
+ .withUnit(Meter.Unit.KB_PER_SEC)
+ .forDevice(deviceId)
+ .burst();
+
+ // Create Meter with single band
+ Band band1 = DefaultBand.builder()
+ .ofType(Band.Type.DROP)
+ .withRate(TEN_M)
+ .burstSize(TWO_K)
+ .build();
+ Meter meter = meterBuilder
+ .fromApp(appId)
+ .withBands(Arrays.asList(band1))
+ .build();
+ BandwidthProfile bandwidthProfile = BandwidthProfile.fromMeter(meter);
+
+ assertEquals("wrong bw profile name",
+ bandwidthProfile.name(), meter.id().toString());
+ assertEquals("wrong bw profile type",
+ bandwidthProfile.type(), BandwidthProfile.Type.sr2CM);
+ assertEquals("wrong bw profile CIR",
+ bandwidthProfile.cir().bps(), band1.rate() * EIGHT_K, 0);
+ assertEquals("wrong bw profile CBS",
+ (long) bandwidthProfile.cbs(), (long) band1.burst());
+ assertNull(bandwidthProfile.pir());
+ assertNull(bandwidthProfile.pbs());
+ assertNull(bandwidthProfile.ebs());
+ assertEquals("wrong green action",
+ bandwidthProfile.greenAction(),
+ getBuilder(Action.PASS).build());
+ assertNull(bandwidthProfile.yellowAction());
+ assertEquals("wrong red action",
+ bandwidthProfile.redAction(),
+ getBuilder(Action.DISCARD).build());
+ assertEquals("wrong color-aware mode",
+ bandwidthProfile.colorAware(), false);
+
+ // Create Meter with two bands
+ Band band2 = DefaultBand.builder().burstSize(ONE_K)
+ .ofType(Band.Type.REMARK)
+ .dropPrecedence((short) 0b001010)
+ .withRate(ONE_M)
+ .build();
+ meter = meterBuilder
+ .fromApp(appId)
+ .withBands(Arrays.asList(band1, band2))
+ .build();
+ bandwidthProfile = BandwidthProfile.fromMeter(meter);
+
+ assertEquals("wrong bw profile name",
+ bandwidthProfile.name(), meter.id().toString());
+ assertEquals("wrong bw profile type",
+ bandwidthProfile.type(), BandwidthProfile.Type.trTCM);
+ assertEquals("wrong bw profile CIR",
+ bandwidthProfile.cir().bps(), band2.rate() * EIGHT_K, 0);
+ assertEquals("wrong bw profile CBS",
+ (long) bandwidthProfile.cbs(), (long) band2.burst());
+ assertEquals("wrong bw profile PIR",
+ bandwidthProfile.pir().bps(), band1.rate() * EIGHT_K, 0);
+ assertEquals("wrong bw profile PBS",
+ (long) bandwidthProfile.pbs(), (long) band1.burst());
+ assertNull(bandwidthProfile.ebs());
+ assertEquals("wrong green action",
+ bandwidthProfile.greenAction(),
+ getBuilder(Action.PASS).build());
+ assertEquals("wrong yellow action",
+ bandwidthProfile.yellowAction(),
+ getBuilder(Action.REMARK)
+ .dscpClass(DscpClass.AF11)
+ .build());
+ assertEquals("wrong red action",
+ bandwidthProfile.redAction(),
+ getBuilder(Action.DISCARD).build());
+ assertEquals("wrong color-aware mode",
+ bandwidthProfile.colorAware(), false);
+ }
+
+ @Test
+ public void testType() {
+ BandwidthProfile.Builder bwProfileBuilder = BandwidthProfile.builder()
+ .name("profile")
+ .cir(Bandwidth.bps(ONE_M))
+ .cbs((int) ONE_K)
+ .greenAction(getBuilder(Action.PASS).build())
+ .redAction(getBuilder(Action.DISCARD).build())
+ .colorAware(false);
+ assertEquals("wrong bw profile type",
+ bwProfileBuilder.build().type(),
+ BandwidthProfile.Type.sr2CM);
+
+ bwProfileBuilder.ebs((int) TWO_K)
+ .yellowAction(getBuilder(Action.REMARK)
+ .dscpClass(DscpClass.AF11)
+ .build());
+ assertEquals("wrong bw profile type",
+ bwProfileBuilder.build().type(),
+ BandwidthProfile.Type.srTCM);
+ bwProfileBuilder.ebs(null);
+
+ bwProfileBuilder.pir(Bandwidth.bps(TEN_M))
+ .pbs((int) TWO_K);
+ assertEquals("wrong bw profile type",
+ bwProfileBuilder.build().type(),
+ BandwidthProfile.Type.trTCM);
+ }
+
+ @Test
+ public void testEquals() {
+ BandwidthProfile bwProfile1 = new BandwidthProfile.Builder()
+ .name("profile1")
+ .cir(Bandwidth.bps(ONE_M))
+ .cbs((int) ONE_K)
+ .pir(Bandwidth.bps(TEN_M))
+ .pbs((int) TWO_K)
+ .greenAction(getBuilder(Action.PASS).build())
+ .yellowAction(getBuilder(Action.REMARK)
+ .dscpClass(DscpClass.AF11)
+ .build())
+ .redAction(getBuilder(Action.DISCARD).build())
+ .colorAware(false)
+ .build();
+ BandwidthProfile bwProfile2 = new BandwidthProfile.Builder()
+ .name("profile2")
+ .cir(Bandwidth.bps(ONE_M))
+ .cbs((int) ONE_K)
+ .pir(Bandwidth.bps(TEN_M))
+ .pbs((int) TWO_K)
+ .greenAction(getBuilder(Action.PASS).build())
+ .yellowAction(getBuilder(Action.REMARK)
+ .dscpClass(DscpClass.AF11)
+ .build())
+ .redAction(getBuilder(Action.DISCARD).build())
+ .colorAware(false)
+ .build();
+ assertTrue("wrong equals method", bwProfile1.equals(bwProfile2));
+ }
+
+ private static BandwidthProfileAction.Builder getBuilder(Action action) {
+ return new BandwidthProfileAction.Builder().action(action);
+ }
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/DscpClass.java b/utils/misc/src/main/java/org/onlab/packet/DscpClass.java
new file mode 100644
index 0000000..14be087
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/DscpClass.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onlab.packet;
+
+/**
+ * Represents the DiffServ classes defined by the IPv4/IPv6 DSCP value.
+ * DSCP occupies the 6 most-significant bits of the IPv4/IPv6 DS field
+ */
+public enum DscpClass {
+
+ BE((short) 0b000000),
+ AF11((short) 0b001010),
+ AF12((short) 0b001100),
+ AF13((short) 0b001110),
+ AF21((short) 0b010010),
+ AF22((short) 0b010100),
+ AF23((short) 0b010110),
+ AF31((short) 0b011010),
+ AF32((short) 0b011100),
+ AF33((short) 0b011110),
+ AF41((short) 0b100010),
+ AF42((short) 0b100100),
+ AF43((short) 0b100110),
+ CS1((short) 0b001000),
+ CS2((short) 0b010000),
+ CS3((short) 0b011000),
+ CS4((short) 0b100000),
+ CS5((short) 0b101000),
+ CS6((short) 0b110000),
+ CS7((short) 0b111000),
+ EF((short) 0b101110);
+
+ private static final short IP_PREC_MASK = 0b111000;
+ private static final short IP_PREC_RSHIFT = 3;
+ private static final short DROP_PREC_MASK = 0b000110;
+ private static final short DROP_PREC_RSHIFT = 1;
+
+ private short value;
+
+ DscpClass(short value) {
+ this.value = value;
+ }
+
+ /**
+ * Returns the DSCP class Enum corresponding to the specified short.
+ *
+ * @param value the short value of the DSCP class
+ * @return the DSCP class Enum corresponding to the specified short
+ * @throws IllegalArgumentException if the short provided does not
+ * correspond to an DSCP class Enum value
+ */
+ public static DscpClass fromShort(short value) {
+ for (DscpClass b : DscpClass.values()) {
+ if (value == b.value) {
+ return b;
+ }
+ }
+ throw new IllegalArgumentException("DSCP class " + value + " is not valid");
+ }
+
+ /**
+ * Returns the short value of this DSCP class Enum.
+ *
+ * @return the short value of this DSCP class Enum
+ */
+ public short getValue() {
+ return value;
+ }
+
+ /**
+ * Returns the corresponding IP precedence.
+ *
+ * @return the corresponding IP precedence
+ */
+ public IPPrecedence getIPPrecedence() {
+ return IPPrecedence.fromShort((short) ((value & IP_PREC_MASK) >> IP_PREC_RSHIFT));
+ }
+
+ /**
+ * Returns the corresponding drop precedence.
+ *
+ * @return the corresponding drop precedence
+ */
+ public short getDropPrecedence() {
+ return (short) ((value & DROP_PREC_MASK) >> DROP_PREC_RSHIFT);
+ }
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/IPPrecedence.java b/utils/misc/src/main/java/org/onlab/packet/IPPrecedence.java
new file mode 100644
index 0000000..09ad0e9
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/IPPrecedence.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onlab.packet;
+
+/**
+ * Represents the deprecated IPv4 IP precedence.
+ * IP precedence occupied the 3 most-significant bits of the IPv4 ToS field
+ */
+public enum IPPrecedence {
+
+ BEST_EFFORT((short) 0b000),
+ PRIORITY((short) 0b001),
+ IMMEDIATE((short) 0b010),
+ FLASH((short) 0b011),
+ FLASH_OVERRIDE((short) 0b100),
+ CRITICAL((short) 0b101),
+ INTERNETWORK_CONTROL((short) 0b110),
+ NETWORK_CONTROL((short) 0b111);
+
+ private short value;
+
+ IPPrecedence(short value) {
+ this.value = value;
+ }
+
+ /**
+ * Returns the IP precedence Enum corresponding to the specified short.
+ *
+ * @param value the short value of the IP precedence
+ * @return the IP precedence Enum corresponding to the specified short
+ * @throws IllegalArgumentException if the short provided does not correspond to an IP precedence Enum value
+ */
+ public static IPPrecedence fromShort(short value) {
+ for (IPPrecedence b : IPPrecedence.values()) {
+ if (value == b.value) {
+ return b;
+ }
+ }
+ throw new IllegalArgumentException("IP precedence " + value + " is not valid");
+ }
+
+ /**
+ * Returns the short value of this IP precedence Enum.
+ *
+ * @return the short value of this IP precedence Enum
+ */
+ public short getValue() {
+ return value;
+ }
+}
diff --git a/utils/misc/src/main/java/org/onlab/util/Bandwidth.java b/utils/misc/src/main/java/org/onlab/util/Bandwidth.java
index bf43bc7..0797dcd 100644
--- a/utils/misc/src/main/java/org/onlab/util/Bandwidth.java
+++ b/utils/misc/src/main/java/org/onlab/util/Bandwidth.java
@@ -86,6 +86,26 @@
}
/**
+ * Creates a new instance with given bandwidth in KBps.
+ *
+ * @param kBps bandwidth value to be assigned
+ * @return {@link Bandwidth} instance with given bandwidth
+ */
+ static Bandwidth kBps(long kBps) {
+ return bps(kBps * 8_000L);
+ }
+
+ /**
+ * Creates a new instance with given bandwidth in KBps.
+ *
+ * @param kBps bandwidth value to be assigned
+ * @return {@link Bandwidth} instance with given bandwidth
+ */
+ static Bandwidth kBps(double kBps) {
+ return bps(kBps * 8_000L);
+ }
+
+ /**
* Creates a new instance with given bandwidth in Mbps.
*
* @param mbps bandwidth value to be assigned
@@ -106,6 +126,26 @@
}
/**
+ * Creates a new instance with given bandwidth in MBps.
+ *
+ * @param mBps bandwidth value to be assigned
+ * @return {@link Bandwidth} instance with given bandwidth
+ */
+ static Bandwidth mBps(long mBps) {
+ return bps(mBps * 8_000_000L);
+ }
+
+ /**
+ * Creates a new instance with given bandwidth in MBps.
+ *
+ * @param mBps bandwidth value to be assigned
+ * @return {@link Bandwidth} instance with given bandwidth
+ */
+ static Bandwidth mBps(double mBps) {
+ return bps(mBps * 8_000_000L);
+ }
+
+ /**
* Creates a new instance with given bandwidth in Gbps.
*
* @param gbps bandwidth value to be assigned
@@ -126,6 +166,26 @@
}
/**
+ * Creates a new instance with given bandwidth in GBps.
+ *
+ * @param gBps bandwidth value to be assigned
+ * @return {@link Bandwidth} instance with given bandwidth
+ */
+ static Bandwidth gBps(long gBps) {
+ return bps(gBps * 8_000_000_000L);
+ }
+
+ /**
+ * Creates a new instance with given bandwidth in GBps.
+ *
+ * @param gBps bandwidth value to be assigned
+ * @return {@link Bandwidth} instance with given bandwidth
+ */
+ static Bandwidth gBps(double gBps) {
+ return bps(gBps * 8_000_000_000L);
+ }
+
+ /**
* Returns bandwidth in bps.
*
* @return bandwidth in bps.
diff --git a/utils/misc/src/test/java/org/onlab/packet/DscpClassTest.java b/utils/misc/src/test/java/org/onlab/packet/DscpClassTest.java
new file mode 100644
index 0000000..295b9e8
--- /dev/null
+++ b/utils/misc/src/test/java/org/onlab/packet/DscpClassTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onlab.packet;
+
+import org.junit.Test;
+
+/**
+ * Test for DscpClassTest enum.
+ */
+public class DscpClassTest {
+ @Test(expected = IllegalArgumentException.class)
+ public void testIllicitDscpClass() {
+ DscpClass.fromShort((short) 0b111001);
+ }
+}
diff --git a/utils/misc/src/test/java/org/onlab/packet/IPPrecedenceTest.java b/utils/misc/src/test/java/org/onlab/packet/IPPrecedenceTest.java
new file mode 100644
index 0000000..999d3c4
--- /dev/null
+++ b/utils/misc/src/test/java/org/onlab/packet/IPPrecedenceTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onlab.packet;
+
+import org.junit.Test;
+
+/**
+ * Test for IPPrecedence enum.
+ */
+public class IPPrecedenceTest {
+ @Test(expected = IllegalArgumentException.class)
+ public void testIllicitIPPrecedence() {
+ IPPrecedence.fromShort((short) 0b1000);
+ }
+}