mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-15 17:31:31 +02:00
[ONOS-7003] Policer implementation
Changes: - Introduce trafficcontrol package - Add policer - Add policer id - Add policing resource - Add token bucket - Add unit tests Change-Id: I70065d58d3df7033e67a81943ebf60187c33c3e2
This commit is contained in:
parent
8b3a5f6751
commit
09220c20d7
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.onosproject.core.ApplicationId;
|
||||
import org.onosproject.net.DeviceId;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.google.common.base.MoreObjects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Default implementation of the policer interface.
|
||||
*/
|
||||
@Beta
|
||||
public final class DefaultPolicer implements Policer, PolicerEntry {
|
||||
|
||||
// Immutable parameters
|
||||
private final DeviceId deviceId;
|
||||
private final ApplicationId applicationId;
|
||||
private final PolicerId policerId;
|
||||
private final boolean colorAware;
|
||||
private final Unit unit;
|
||||
private final Collection<TokenBucket> tokenBuckets;
|
||||
private final String description;
|
||||
|
||||
// Mutable parameters
|
||||
private long referenceCount;
|
||||
private long processedPackets;
|
||||
private long processedBytes;
|
||||
private long life;
|
||||
|
||||
private DefaultPolicer(DeviceId dId, ApplicationId aId, PolicerId pId,
|
||||
boolean cA, Unit u, Collection<TokenBucket> tB,
|
||||
String d) {
|
||||
deviceId = dId;
|
||||
applicationId = aId;
|
||||
policerId = pId;
|
||||
colorAware = cA;
|
||||
unit = u;
|
||||
tokenBuckets = tB;
|
||||
description = d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceId deviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationId applicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PolicerId policerId() {
|
||||
return policerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isColorAware() {
|
||||
return colorAware;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Unit unit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<TokenBucket> tokenBuckets() {
|
||||
return tokenBuckets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long referenceCount() {
|
||||
return referenceCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReferenceCount(long count) {
|
||||
referenceCount = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long processedPackets() {
|
||||
return processedPackets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessedPackets(long packets) {
|
||||
processedPackets = packets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long processedBytes() {
|
||||
return processedBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessedBytes(long bytes) {
|
||||
processedBytes = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long life() {
|
||||
return life;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLife(long l) {
|
||||
life = l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this)
|
||||
.add("appId", applicationId())
|
||||
.add("id", policerId())
|
||||
.add("isColorAware", isColorAware())
|
||||
.add("unit", unit())
|
||||
.add("tokenBuckets", tokenBuckets())
|
||||
.add("description", description())
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DefaultPolicer that = (DefaultPolicer) o;
|
||||
return Objects.equal(policerId, that.policerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return policerId.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new builder reference.
|
||||
*
|
||||
* @return a new builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the policer builder interface.
|
||||
*/
|
||||
public static final class Builder implements Policer.Builder {
|
||||
|
||||
private DeviceId deviceId;
|
||||
private ApplicationId applicationId;
|
||||
private PolicerId policerId;
|
||||
// Default to unaware
|
||||
private boolean colorAware = false;
|
||||
// Default to MBps
|
||||
private Unit unit = Unit.MB_PER_SEC;
|
||||
private Collection<TokenBucket> tokenBuckets;
|
||||
private String description = "";
|
||||
|
||||
@Override
|
||||
public Policer.Builder forDeviceId(DeviceId dId) {
|
||||
deviceId = dId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policer.Builder fromApp(ApplicationId appId) {
|
||||
applicationId = appId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policer.Builder withId(PolicerId id) {
|
||||
policerId = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policer.Builder colorAware(boolean isColorAware) {
|
||||
colorAware = isColorAware;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policer.Builder withUnit(Unit u) {
|
||||
unit = u;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policer.Builder withPolicingResource(PolicingResource policingResource) {
|
||||
policerId = policingResource.policerId();
|
||||
deviceId = policingResource.connectPoint().deviceId();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policer.Builder withTokenBuckets(Collection<TokenBucket> tB) {
|
||||
tokenBuckets = ImmutableSet.copyOf(tB);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policer.Builder withDescription(String d) {
|
||||
description = d;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultPolicer build() {
|
||||
// Not null condition on some mandatory parameters
|
||||
checkNotNull(deviceId, "Must specify a deviceId");
|
||||
checkNotNull(applicationId, "Must specify an application id");
|
||||
checkNotNull(policerId, "Must specify a policer id");
|
||||
checkNotNull(unit, "Must specify a unit for the policer");
|
||||
checkNotNull(tokenBuckets, "Must have token buckets");
|
||||
checkNotNull(description, "Must have a description");
|
||||
|
||||
// Verify argument conditions
|
||||
checkArgument(!tokenBuckets.isEmpty(), "Must have at least one token bucket");
|
||||
|
||||
// Finally we build the policer
|
||||
return new DefaultPolicer(deviceId, applicationId, policerId,
|
||||
colorAware, unit, tokenBuckets,
|
||||
description);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import static com.google.common.base.MoreObjects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.TokenBucket.Action.DSCP_CLASS;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.TokenBucket.Action.DSCP_PRECEDENCE;
|
||||
|
||||
/**
|
||||
* Default implementation of the token bucket interface.
|
||||
*/
|
||||
@Beta
|
||||
public final class DefaultTokenBucket implements TokenBucket, TokenBucketEntry {
|
||||
|
||||
// Immutable parameters
|
||||
private final long rate;
|
||||
private final long burstSize;
|
||||
private final Action action;
|
||||
private final short dscp;
|
||||
|
||||
// Mutable parameters
|
||||
private long processedPackets;
|
||||
private long processedBytes;
|
||||
|
||||
private DefaultTokenBucket(long r, long bS, Action a, short d) {
|
||||
rate = r;
|
||||
burstSize = bS;
|
||||
action = a;
|
||||
dscp = d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long rate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long burstSize() {
|
||||
return burstSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action action() {
|
||||
return action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short dscp() {
|
||||
return dscp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long processedPackets() {
|
||||
return processedPackets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessedPackets(long packets) {
|
||||
processedPackets = packets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long processedBytes() {
|
||||
return processedBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessedBytes(long bytes) {
|
||||
processedBytes = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this)
|
||||
.add("rate", rate())
|
||||
.add("burstSize", burstSize())
|
||||
.add("action", action())
|
||||
.add("dscp", dscp()).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DefaultTokenBucket that = (DefaultTokenBucket) o;
|
||||
return rate == that.rate &&
|
||||
burstSize == that.burstSize &&
|
||||
Objects.equal(action, that.action) &&
|
||||
dscp == that.dscp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(rate, burstSize, action, dscp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new builder reference.
|
||||
*
|
||||
* @return a new builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the token bucket builder interface.
|
||||
*/
|
||||
public static final class Builder implements TokenBucket.Builder {
|
||||
|
||||
private long rate;
|
||||
// Default to 2 * MTU
|
||||
private long burstSize = 2 * 1500;
|
||||
private Action action;
|
||||
private short dscp;
|
||||
|
||||
@Override
|
||||
public TokenBucket.Builder withRate(long r) {
|
||||
rate = r;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenBucket.Builder withBurstSize(long bS) {
|
||||
burstSize = bS;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenBucket.Builder withAction(Action a) {
|
||||
action = a;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenBucket.Builder withDscp(short d) {
|
||||
dscp = d;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultTokenBucket build() {
|
||||
// Not null condition on the action
|
||||
checkNotNull(action, "Must specify an action");
|
||||
|
||||
// If action is based on DSCP modification
|
||||
if (action == DSCP_CLASS || action == DSCP_PRECEDENCE) {
|
||||
// dscp should be a value between 0 and 255
|
||||
checkArgument(dscp >= MIN_DSCP && dscp <= MAX_DSCP, "Dscp is out of range");
|
||||
}
|
||||
|
||||
// Finally we build the token bucket
|
||||
return new DefaultTokenBucket(rate, burstSize, action, dscp);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import org.onosproject.core.ApplicationId;
|
||||
import org.onosproject.net.DeviceId;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Generic abstraction for a policer which can mark and/or discard ingress
|
||||
* traffic. Each policer is made up of an identifier and a set of attributes
|
||||
* which defines the type of policer.
|
||||
* <p>
|
||||
* For example a policer specifying only a single token bucket, it will model
|
||||
* a simple drop policer or a marker policer. For the former, the traffic in
|
||||
* profile is green or red if it is out-of-profile. The latter envisages green
|
||||
* or yellow traffic. Currently there is no RFC for this kind of policer but
|
||||
* some vendors implement this model.
|
||||
* <p>
|
||||
* RFC 2697 can be modelled creating a policer with a collection of two
|
||||
* token buckets: [0] CIR + CBS; [1] CIR + EBS. In this way, it is possible
|
||||
* to create a policer single rate three color marker.
|
||||
* <p>
|
||||
* RFC 2698 and P4 meter are modelled in the same way but different attributes
|
||||
* for the token buckets: [0] PIR + PBS; [2] CIR + CBS. In this way, we can
|
||||
* create a policer two rate three color marker.
|
||||
* <p>
|
||||
* How these policers will be implemented depends on the specific technology
|
||||
* used in the device. For an OF device, the single rate two color marker it
|
||||
* could be implemented with a simple meter with a drop band.
|
||||
* <p>
|
||||
* Following abstraction has been designed to cover several types of policing
|
||||
* that have been specified during the years. However, this does not assure that
|
||||
* used technology will support all possible scenarios. For example, OF limitations
|
||||
* are well known in this field and implementations are even worse.
|
||||
*/
|
||||
@Beta
|
||||
public interface Policer {
|
||||
|
||||
/**
|
||||
* Unit of traffic used by this policer.
|
||||
*/
|
||||
enum Unit {
|
||||
/**
|
||||
* Packets per second.
|
||||
*/
|
||||
PKTS_PER_SEC,
|
||||
/**
|
||||
* Byte per second.
|
||||
*/
|
||||
B_PER_SEC,
|
||||
/**
|
||||
* KByte per second.
|
||||
*/
|
||||
KB_PER_SEC,
|
||||
/**
|
||||
* MByte per second.
|
||||
*/
|
||||
MB_PER_SEC
|
||||
}
|
||||
|
||||
/**
|
||||
* The device of this policer, where policing
|
||||
* is applied.
|
||||
*
|
||||
* @return the device id
|
||||
*/
|
||||
DeviceId deviceId();
|
||||
|
||||
/**
|
||||
* The id of the application which created this policer.
|
||||
*
|
||||
* @return the identifier of the application
|
||||
*/
|
||||
ApplicationId applicationId();
|
||||
|
||||
/**
|
||||
* Returns how many are referencing this policer.
|
||||
*
|
||||
* Availability of this information depends on the
|
||||
* technology used for the implementation of this policer.
|
||||
*
|
||||
* @return the reference count
|
||||
*/
|
||||
long referenceCount();
|
||||
|
||||
/**
|
||||
* Stats which reports how many packets have been
|
||||
* processed so far.
|
||||
*
|
||||
* Availability of this information depends on the
|
||||
* technology used for the implementation of this policer.
|
||||
*
|
||||
* @return the processed packets
|
||||
*/
|
||||
long processedPackets();
|
||||
|
||||
/**
|
||||
* Stats which reports how many bytes have been
|
||||
* processed so far.
|
||||
*
|
||||
* Availability of this information depends on the
|
||||
* technology used for the implementation of this policer.
|
||||
*
|
||||
* @return the processed bytes
|
||||
*/
|
||||
long processedBytes();
|
||||
|
||||
/**
|
||||
* The id of this policer.
|
||||
*
|
||||
* @return the policer id
|
||||
*/
|
||||
PolicerId policerId();
|
||||
|
||||
/**
|
||||
* Indicates if this policer is aware of the marking indication
|
||||
* in the ethernet frames.
|
||||
*
|
||||
* TODO Understand for the future how it is implemented by the vendors
|
||||
*
|
||||
* @return true if this policer is color aware.
|
||||
*/
|
||||
boolean isColorAware();
|
||||
|
||||
/**
|
||||
* The lifetime in seconds of this policer.
|
||||
*
|
||||
* Availability of this information depends on the
|
||||
* technology used for the implementation of this policer.
|
||||
*
|
||||
* @return number of seconds
|
||||
*/
|
||||
long life();
|
||||
|
||||
/**
|
||||
* The unit used within this policer.
|
||||
*
|
||||
* @return the unit
|
||||
*/
|
||||
Unit unit();
|
||||
|
||||
/**
|
||||
* The token buckets used within this policer.
|
||||
*
|
||||
* @return the list of the token buckets
|
||||
*/
|
||||
Collection<TokenBucket> tokenBuckets();
|
||||
|
||||
/**
|
||||
* Brief description of this policer.
|
||||
*
|
||||
* @return human readable description
|
||||
*/
|
||||
String description();
|
||||
|
||||
/**
|
||||
* A policer builder.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Assigns the device for this policer.
|
||||
* <p>
|
||||
* Note: mandatory setter for this builder
|
||||
* </p>
|
||||
* @param deviceId a device id
|
||||
* @return this
|
||||
*/
|
||||
Builder forDeviceId(DeviceId deviceId);
|
||||
|
||||
/**
|
||||
* Assigns the application that built this policer.
|
||||
* <p>
|
||||
* Note: mandatory setter for this builder
|
||||
* </p>
|
||||
* @param appId an application id
|
||||
* @return this
|
||||
*/
|
||||
Builder fromApp(ApplicationId appId);
|
||||
|
||||
/**
|
||||
* Assigns the id to this policer.
|
||||
* <p>
|
||||
* Note: mandatory setter for this builder
|
||||
* </p>
|
||||
* @param id an identifier
|
||||
* @return this
|
||||
*/
|
||||
Builder withId(PolicerId id);
|
||||
|
||||
/**
|
||||
* Sets this policer to be color aware.
|
||||
* Defaults to false.
|
||||
*
|
||||
* @param isColorAware if it is color aware or not
|
||||
* @return this
|
||||
*/
|
||||
Builder colorAware(boolean isColorAware);
|
||||
|
||||
/**
|
||||
* Assigns the unit to use for this policer.
|
||||
* Defaults to MB/s.
|
||||
*
|
||||
* @param unit a unit
|
||||
* @return this
|
||||
*/
|
||||
Builder withUnit(Unit unit);
|
||||
|
||||
/**
|
||||
* Assigns policer id and device id for this policer.
|
||||
*
|
||||
* @param policingResource the policing resource
|
||||
* @return this
|
||||
*/
|
||||
Builder withPolicingResource(PolicingResource policingResource);
|
||||
|
||||
/**
|
||||
* Assigns token buckets for this policer.
|
||||
* <p>
|
||||
* Note: at least one token bucket
|
||||
* </p>
|
||||
* @param tokenBuckets the collection of token buckets
|
||||
* @return this
|
||||
*/
|
||||
Builder withTokenBuckets(Collection<TokenBucket> tokenBuckets);
|
||||
|
||||
/**
|
||||
* Assigns description for this policer.
|
||||
* Default is empty description.
|
||||
*
|
||||
* @param description the description
|
||||
* @return this
|
||||
*/
|
||||
Builder withDescription(String description);
|
||||
|
||||
/**
|
||||
* Builds the policer based on the specified parameters
|
||||
* when possible.
|
||||
*
|
||||
* @return a policer
|
||||
*/
|
||||
Policer build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Represents a stored policer.
|
||||
*/
|
||||
@Beta
|
||||
public interface PolicerEntry {
|
||||
|
||||
/**
|
||||
* Set the amount of time the policer has existed in seconds.
|
||||
*
|
||||
* @param life number of seconds
|
||||
*/
|
||||
void setLife(long life);
|
||||
|
||||
/**
|
||||
* Sets how many are using this policer.
|
||||
*
|
||||
* @param count a reference count.
|
||||
*/
|
||||
void setReferenceCount(long count);
|
||||
|
||||
/**
|
||||
* Updates the number of packets seen by this policer.
|
||||
*
|
||||
* @param packets a packet count.
|
||||
*/
|
||||
void setProcessedPackets(long packets);
|
||||
|
||||
/**
|
||||
* Updates the number of bytes seen by the policer.
|
||||
*
|
||||
* @param bytes a byte counter.
|
||||
*/
|
||||
void setProcessedBytes(long bytes);
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import org.onlab.util.Identifier;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
* Unique identifier for an ONOS Policer {@link org.onosproject.net.behaviour.trafficcontrol.Policer}.
|
||||
* It uniquely identifies a Policer in the scope of a single device inside ONOS. There may not be any
|
||||
* correspondence with the identifiers of the technology implementing the Policer in the device.
|
||||
* Mapping (if necessary) is left to the specific implementation.
|
||||
*/
|
||||
@Beta
|
||||
public final class PolicerId extends Identifier<String> {
|
||||
|
||||
/**
|
||||
* Represents either no id, or an unspecified id.
|
||||
*/
|
||||
public static final PolicerId NONE = policerId("none:none");
|
||||
|
||||
private static final int POLICER_ID_MAX_LENGTH = 1024;
|
||||
|
||||
private final URI uri;
|
||||
|
||||
// Not allowed
|
||||
private PolicerId(URI u) {
|
||||
super(u.toString());
|
||||
uri = u;
|
||||
}
|
||||
|
||||
// Needed for serialization
|
||||
private PolicerId() {
|
||||
super();
|
||||
uri = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a policer id using the supplied URI.
|
||||
*
|
||||
* @param uri policer id URI
|
||||
* @return PolicerId
|
||||
*/
|
||||
public static PolicerId policerId(URI uri) {
|
||||
return new PolicerId(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a policer id using the supplied URI string.
|
||||
*
|
||||
* @param string policer id URI string
|
||||
* @return PolicerID
|
||||
*/
|
||||
public static PolicerId policerId(String string) {
|
||||
checkArgument(string.length() <= POLICER_ID_MAX_LENGTH,
|
||||
"URI string exceeds maximum length " + POLICER_ID_MAX_LENGTH);
|
||||
return policerId(URI.create(string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the backing URI.
|
||||
*
|
||||
* @return backing URI
|
||||
*/
|
||||
public URI uri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import org.onosproject.net.ConnectPoint;
|
||||
import org.onosproject.net.NetworkResource;
|
||||
|
||||
import static com.google.common.base.MoreObjects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Abstraction which encapsulates policer
|
||||
* data to be used as network resource.
|
||||
*/
|
||||
@Beta
|
||||
public final class PolicingResource implements NetworkResource {
|
||||
|
||||
// The policer id identifying this resource
|
||||
private final PolicerId policerId;
|
||||
// The connect point where the policer applies
|
||||
private final ConnectPoint connectPoint;
|
||||
|
||||
public PolicingResource(PolicerId pId, ConnectPoint cP) {
|
||||
checkNotNull(pId, "Must specify a policer id");
|
||||
checkNotNull(cP, "Must specify a connect point");
|
||||
policerId = pId;
|
||||
connectPoint = cP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the policer id of this resource.
|
||||
*
|
||||
* @return the policer id
|
||||
*/
|
||||
public PolicerId policerId() {
|
||||
return policerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the connect point of this resource.
|
||||
*
|
||||
* @return the connect point
|
||||
*/
|
||||
public ConnectPoint connectPoint() {
|
||||
return connectPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this)
|
||||
.add("id", policerId())
|
||||
.add("connectPoint", connectPoint()).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
PolicingResource that = (PolicingResource) o;
|
||||
return Objects.equal(policerId, that.policerId) &&
|
||||
Objects.equal(connectPoint, that.connectPoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(policerId, connectPoint);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Generic abstraction for a token bucket which can mark and/or discard
|
||||
* traffic. Each token bucket in ONOS is made up of a set of attributes which
|
||||
* identifies the type.
|
||||
*/
|
||||
@Beta
|
||||
public interface TokenBucket {
|
||||
|
||||
/**
|
||||
* Upper bound for DSCP.
|
||||
*/
|
||||
short MAX_DSCP = 255;
|
||||
/**
|
||||
* Lower bound for DSCP.
|
||||
*/
|
||||
short MIN_DSCP = 0;
|
||||
|
||||
/**
|
||||
* Action applied to the exceeding traffic.
|
||||
* Action depends on the tocken bucket type
|
||||
*/
|
||||
enum Action {
|
||||
/**
|
||||
* Drop action.
|
||||
*/
|
||||
DROP,
|
||||
/**
|
||||
* Marking increases DSCP drop precedence.
|
||||
*/
|
||||
DSCP_PRECEDENCE,
|
||||
/**
|
||||
* Marking sets DSCP class.
|
||||
*/
|
||||
DSCP_CLASS,
|
||||
/**
|
||||
* Marking sets Drop Elegible Indicator.
|
||||
*/
|
||||
DEI
|
||||
}
|
||||
|
||||
/**
|
||||
* Rate of traffic subject to the SLAs
|
||||
* specified for this token bucket.
|
||||
*
|
||||
* @return the rate value
|
||||
*/
|
||||
long rate();
|
||||
|
||||
/**
|
||||
* Maximum burst size subject to the SLAs
|
||||
* specified for this token bucket.
|
||||
*
|
||||
* @return the burst size in bytes
|
||||
*/
|
||||
long burstSize();
|
||||
|
||||
/**
|
||||
* Action used by this token bucket
|
||||
* for the exceeding traffic.
|
||||
*
|
||||
* @return the type of action
|
||||
*/
|
||||
Action action();
|
||||
|
||||
/**
|
||||
* Dscp value, it meaning depends on the used marking.
|
||||
*
|
||||
* @return the dscp value for this token bucket
|
||||
*/
|
||||
short dscp();
|
||||
|
||||
/**
|
||||
* Stats which reports how many packets have been
|
||||
* processed so far.
|
||||
*
|
||||
* Availability of this information depends on the
|
||||
* technology used for the implementation of the policer.
|
||||
*
|
||||
* @return the processed packets
|
||||
*/
|
||||
long processedPackets();
|
||||
|
||||
/**
|
||||
* Stats which reports how many bytes have been
|
||||
* processed so far.
|
||||
*
|
||||
* Availability of this information depends on the
|
||||
* technology used for the implementation of the policer.
|
||||
*
|
||||
* @return the processed bytes
|
||||
*/
|
||||
long processedBytes();
|
||||
|
||||
/**
|
||||
* Token bucket builder.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Assigns the rate to this token bucket.
|
||||
*
|
||||
* @param rate a rate value
|
||||
* @return this
|
||||
*/
|
||||
Builder withRate(long rate);
|
||||
|
||||
/**
|
||||
* Assigns the burst size to this token bucket.
|
||||
* Default to 2 * 1500 bytes.
|
||||
*
|
||||
* @param burstSize a burst size
|
||||
* @return this
|
||||
*/
|
||||
Builder withBurstSize(long burstSize);
|
||||
|
||||
/**
|
||||
* Assigns the action to this token bucket.
|
||||
* <p>
|
||||
* Note: mandatory setter for this builder
|
||||
* </p>
|
||||
* @param action an action
|
||||
* @return this
|
||||
*/
|
||||
Builder withAction(Action action);
|
||||
|
||||
/**
|
||||
* Assigns the dscp value to this token bucket.
|
||||
*
|
||||
* @param dscp a dscp value
|
||||
* @return this
|
||||
*/
|
||||
Builder withDscp(short dscp);
|
||||
|
||||
/**
|
||||
* Builds the token bucket based on the specified
|
||||
* parameters when possible.
|
||||
*
|
||||
* @return a token bucket
|
||||
*/
|
||||
TokenBucket build();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Represents a stored token bucket.
|
||||
*/
|
||||
@Beta
|
||||
public interface TokenBucketEntry {
|
||||
|
||||
/**
|
||||
* Updates the number of packets seen by this token bucket.
|
||||
*
|
||||
* @param packets a packet count.
|
||||
*/
|
||||
void setProcessedPackets(long packets);
|
||||
|
||||
/**
|
||||
* Updates the number of bytes seen by this token bucket.
|
||||
*
|
||||
* @param bytes a byte counter.
|
||||
*/
|
||||
void setProcessedBytes(long bytes);
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Traffic control behaviors and related classes.
|
||||
*/
|
||||
package org.onosproject.net.behaviour.trafficcontrol;
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.onlab.junit.ImmutableClassChecker;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Test class for PolicerId.
|
||||
*/
|
||||
public class PolicerIdTest {
|
||||
|
||||
// Test scheme
|
||||
private static final String FOO_SCHEME = "foo";
|
||||
// OpenFlow scheme
|
||||
private static final String OF_SCHEME = "of";
|
||||
// Some test ids
|
||||
private static final Short ONE = 1;
|
||||
private static final Short TWO = 15;
|
||||
private static final String A = "A";
|
||||
private static final String LA = "a";
|
||||
|
||||
/**
|
||||
* Test policer id creation from URI.
|
||||
*/
|
||||
@Test
|
||||
public void testfromUriCreation() {
|
||||
// Create URI representing the id
|
||||
URI uriOne = URI.create(OF_SCHEME + ":" + Integer.toHexString(ONE));
|
||||
// Create policer id
|
||||
PolicerId one = PolicerId.policerId(uriOne);
|
||||
// Verify proper creation
|
||||
assertThat(one, notNullValue());
|
||||
assertThat(one.id(), is(uriOne.toString().toLowerCase()));
|
||||
assertThat(one.uri(), is(uriOne));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test policer id creation from string.
|
||||
*/
|
||||
@Test
|
||||
public void testfromStringCreation() {
|
||||
// Create String representing the id
|
||||
String stringTwo = OF_SCHEME + ":" + Integer.toHexString(TWO);
|
||||
// Create policer id
|
||||
PolicerId two = PolicerId.policerId(stringTwo);
|
||||
// Verify proper creation
|
||||
assertThat(two, notNullValue());
|
||||
assertThat(two.id(), is(stringTwo));
|
||||
assertThat(two.uri(), is(URI.create(stringTwo)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception expected to raise when creating a wrong policer id.
|
||||
*/
|
||||
@Rule
|
||||
public ExpectedException exceptionWrongId = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Test wrong creation of a policer id.
|
||||
*/
|
||||
@Test
|
||||
public void testWrongCreation() {
|
||||
// Build not allowed string
|
||||
String wrongString = Strings.repeat("x", 1025);
|
||||
// Define expected exception
|
||||
exceptionWrongId.expect(IllegalArgumentException.class);
|
||||
// Create policer id
|
||||
PolicerId.policerId(wrongString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test equality between policer ids.
|
||||
*/
|
||||
@Test
|
||||
public void testEquality() {
|
||||
// Create URI representing the id one
|
||||
URI uriOne = URI.create(OF_SCHEME + ":" + Integer.toHexString(ONE));
|
||||
// Create String representing the id one
|
||||
String stringOne = OF_SCHEME + ":" + Integer.toHexString(ONE);
|
||||
// Create String representing the id two
|
||||
String stringTwo = OF_SCHEME + ":" + Integer.toHexString(TWO);
|
||||
// Create String representing the id A
|
||||
String stringA = FOO_SCHEME + ":" + A;
|
||||
// Create String representing the id LA
|
||||
String stringLA = FOO_SCHEME + ":" + LA;
|
||||
// Create policer id one
|
||||
PolicerId one = PolicerId.policerId(uriOne);
|
||||
// Create policer id one
|
||||
PolicerId copyOfOne = PolicerId.policerId(stringOne);
|
||||
// Verify equality
|
||||
assertEquals(one, copyOfOne);
|
||||
// Create a different policer id
|
||||
PolicerId two = PolicerId.policerId(stringTwo);
|
||||
// Verify not equals
|
||||
assertNotEquals(two, one);
|
||||
assertNotEquals(two, copyOfOne);
|
||||
// Create policer id A
|
||||
PolicerId a = PolicerId.policerId(A);
|
||||
// Create policer id LA
|
||||
PolicerId la = PolicerId.policerId(LA);
|
||||
// Verify not equals
|
||||
assertNotEquals(a, la);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests immutability of PolicerId.
|
||||
*/
|
||||
@Test
|
||||
public void testImmutability() {
|
||||
ImmutableClassChecker.assertThatClassIsImmutable(PolicerId.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,343 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.onosproject.TestApplicationId;
|
||||
import org.onosproject.core.ApplicationId;
|
||||
import org.onosproject.net.DeviceId;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.Policer.Unit.KB_PER_SEC;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.Policer.Unit.MB_PER_SEC;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.TokenBucket.Action.DROP;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.TokenBucket.Action.DSCP_CLASS;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.TokenBucket.Action.DSCP_PRECEDENCE;
|
||||
|
||||
/**
|
||||
* Test class for policer implementation.
|
||||
*/
|
||||
public class PolicerTest {
|
||||
|
||||
// Fake Application Id
|
||||
private static final ApplicationId FOO_APP_ID = new TestApplicationId("foo");
|
||||
// Connect points
|
||||
private static final String SDID1 = "of:00000000000001";
|
||||
private static final DeviceId DID1 = DeviceId.deviceId(SDID1);
|
||||
// OpenFlow scheme
|
||||
private static final String OF_SCHEME = "of";
|
||||
// Policers identifiers
|
||||
private static final String SID1 = OF_SCHEME + ":" + Integer.toHexString(1);
|
||||
private static final PolicerId ID1 = PolicerId.policerId(SID1);
|
||||
private static final String SID2 = OF_SCHEME + ":" + Integer.toHexString(2);
|
||||
private static final PolicerId ID2 = PolicerId.policerId(SID2);
|
||||
private static final String SID3 = OF_SCHEME + ":" + Integer.toHexString(3);
|
||||
private static final PolicerId ID3 = PolicerId.policerId(SID3);
|
||||
private static final String SID4 = OF_SCHEME + ":" + Integer.toHexString(4);
|
||||
private static final PolicerId ID4 = PolicerId.policerId(SID4);
|
||||
private static final String SID5 = OF_SCHEME + ":" + Integer.toHexString(5);
|
||||
private static final PolicerId ID5 = PolicerId.policerId(SID5);
|
||||
private static final String SID6 = OF_SCHEME + ":" + Integer.toHexString(6);
|
||||
private static final PolicerId ID6 = PolicerId.policerId(SID6);
|
||||
private static final String SID7 = OF_SCHEME + ":" + Integer.toHexString(7);
|
||||
private static final PolicerId ID7 = PolicerId.policerId(SID7);
|
||||
private static final String SID8 = OF_SCHEME + ":" + Integer.toHexString(8);
|
||||
private static final PolicerId ID8 = PolicerId.policerId(SID8);
|
||||
private static final String SID9 = OF_SCHEME + ":" + Integer.toHexString(9);
|
||||
private static final PolicerId ID9 = PolicerId.policerId(SID9);
|
||||
|
||||
/**
|
||||
* Test block traffic policer.
|
||||
*/
|
||||
@Test
|
||||
public void testBlockCreation() {
|
||||
// Create a block traffic token bucket
|
||||
TokenBucket tokenBucket = DefaultTokenBucket.builder()
|
||||
.withBurstSize(0)
|
||||
.withAction(DROP)
|
||||
.build();
|
||||
// Create a policer with above token bucket
|
||||
Policer policer = DefaultPolicer.builder()
|
||||
.forDeviceId(DID1)
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID1)
|
||||
.withTokenBuckets(ImmutableList.of(tokenBucket))
|
||||
.build();
|
||||
// Assert on device id
|
||||
assertThat(policer.deviceId(), is(DID1));
|
||||
// Assert on app id
|
||||
assertThat(policer.applicationId(), is(FOO_APP_ID));
|
||||
// Assert on policer id
|
||||
assertThat(policer.policerId(), is(ID1));
|
||||
// It is not color aware
|
||||
assertFalse(policer.isColorAware());
|
||||
// Unit is Mbps
|
||||
assertThat(policer.unit(), is(MB_PER_SEC));
|
||||
// One token bucket
|
||||
assertThat(policer.tokenBuckets().size(), is(1));
|
||||
// One token bucket equals to tokenBucket
|
||||
assertTrue(policer.tokenBuckets().contains(tokenBucket));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test simple drop policer.
|
||||
*/
|
||||
@Test
|
||||
public void testDropCreation() {
|
||||
// Create a drop traffic token bucket at 1MB/s
|
||||
TokenBucket tokenBucket = DefaultTokenBucket.builder()
|
||||
.withRate(1)
|
||||
.withAction(DROP)
|
||||
.build();
|
||||
// Create a policer with above token bucket
|
||||
Policer policer = DefaultPolicer.builder()
|
||||
.forDeviceId(DID1)
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID2)
|
||||
.withTokenBuckets(ImmutableList.of(tokenBucket))
|
||||
.build();
|
||||
// Assert on device id
|
||||
assertThat(policer.deviceId(), is(DID1));
|
||||
// Assert on app id
|
||||
assertThat(policer.applicationId(), is(FOO_APP_ID));
|
||||
// Assert on policer id
|
||||
assertThat(policer.policerId(), is(ID2));
|
||||
// It is not color aware
|
||||
assertFalse(policer.isColorAware());
|
||||
// Unit is Mbps
|
||||
assertThat(policer.unit(), is(MB_PER_SEC));
|
||||
// One token bucket
|
||||
assertThat(policer.tokenBuckets().size(), is(1));
|
||||
// One token bucket equals to tokenBucket
|
||||
assertTrue(policer.tokenBuckets().contains(tokenBucket));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test simple mark policer.
|
||||
*/
|
||||
@Test
|
||||
public void testMarkCreation() {
|
||||
// Create a drop traffic token bucket at 1MB/s
|
||||
TokenBucket tokenBucket = DefaultTokenBucket.builder()
|
||||
.withRate(1)
|
||||
.withAction(DSCP_PRECEDENCE)
|
||||
.withDscp((short) 2)
|
||||
.build();
|
||||
// Create a policer with above token bucket
|
||||
Policer policer = DefaultPolicer.builder()
|
||||
.forDeviceId(DID1)
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID3)
|
||||
.withTokenBuckets(ImmutableList.of(tokenBucket))
|
||||
.build();
|
||||
// Assert on device id
|
||||
assertThat(policer.deviceId(), is(DID1));
|
||||
// Assert on app id
|
||||
assertThat(policer.applicationId(), is(FOO_APP_ID));
|
||||
// Assert on policer id
|
||||
assertThat(policer.policerId(), is(ID3));
|
||||
// It is not color aware
|
||||
assertFalse(policer.isColorAware());
|
||||
// Unit is Mbps
|
||||
assertThat(policer.unit(), is(MB_PER_SEC));
|
||||
// One token bucket
|
||||
assertThat(policer.tokenBuckets().size(), is(1));
|
||||
// One token bucket equals to tokenBucket
|
||||
assertTrue(policer.tokenBuckets().contains(tokenBucket));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test single rate three colors scenario (RFC 2697).
|
||||
*/
|
||||
@Test
|
||||
public void testSingleRateThreeColors() {
|
||||
// Create token bucket for committed rate
|
||||
TokenBucket crTokenBucket = DefaultTokenBucket.builder()
|
||||
.withRate(1)
|
||||
.withAction(DSCP_PRECEDENCE)
|
||||
.withDscp((short) 2)
|
||||
.build();
|
||||
// Create token bucket for excess rate
|
||||
TokenBucket erTokenBucket = DefaultTokenBucket.builder()
|
||||
.withRate(1)
|
||||
.withBurstSize(4 * 1500)
|
||||
.withAction(DROP)
|
||||
.build();
|
||||
// Create a policer with above token buckets
|
||||
Policer policer = DefaultPolicer.builder()
|
||||
.forDeviceId(DID1)
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID4)
|
||||
// The order is important
|
||||
.withTokenBuckets(ImmutableList.of(crTokenBucket, erTokenBucket))
|
||||
.build();
|
||||
// Assert on device id
|
||||
assertThat(policer.deviceId(), is(DID1));
|
||||
// Assert on app id
|
||||
assertThat(policer.applicationId(), is(FOO_APP_ID));
|
||||
// Assert on policer id
|
||||
assertThat(policer.policerId(), is(ID4));
|
||||
// It is not color aware
|
||||
assertFalse(policer.isColorAware());
|
||||
// Unit is Mbps
|
||||
assertThat(policer.unit(), is(MB_PER_SEC));
|
||||
// Two token buckets
|
||||
assertThat(policer.tokenBuckets().size(), is(2));
|
||||
// One token bucket equals to crTokenBucket
|
||||
assertTrue(policer.tokenBuckets().contains(crTokenBucket));
|
||||
// One token bucket equals to erTokenBucket
|
||||
assertTrue(policer.tokenBuckets().contains(erTokenBucket));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test two rates three colors scenario (RFC 2698 and P4 meter).
|
||||
*/
|
||||
@Test
|
||||
public void testTwoRatesThreeColors() {
|
||||
// Create token bucket for peak rate at 10Mb/s
|
||||
TokenBucket prTokenBucket = DefaultTokenBucket.builder()
|
||||
// (10 * 1000)/8 ---> 1250KB/s
|
||||
.withRate(1250)
|
||||
.withBurstSize(10 * 1500)
|
||||
.withAction(DROP)
|
||||
.build();
|
||||
// Create token bucket for committed rate at 1Mb/s
|
||||
TokenBucket crTokenBucket = DefaultTokenBucket.builder()
|
||||
// (1 * 1000)/8 ---> 125KB/s
|
||||
.withRate(125)
|
||||
.withAction(DSCP_CLASS)
|
||||
.withDscp((short) 10)
|
||||
.build();
|
||||
// Create a policer with above token buckets
|
||||
Policer policer = DefaultPolicer.builder()
|
||||
.forDeviceId(DID1)
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID5)
|
||||
.withUnit(KB_PER_SEC)
|
||||
// The order is important
|
||||
.withTokenBuckets(ImmutableList.of(prTokenBucket, crTokenBucket))
|
||||
.build();
|
||||
// Assert on device id
|
||||
assertThat(policer.deviceId(), is(DID1));
|
||||
// Assert on app id
|
||||
assertThat(policer.applicationId(), is(FOO_APP_ID));
|
||||
// Assert on policer id
|
||||
assertThat(policer.policerId(), is(ID5));
|
||||
// It is not color aware
|
||||
assertFalse(policer.isColorAware());
|
||||
// Unit is Mbps
|
||||
assertThat(policer.unit(), is(KB_PER_SEC));
|
||||
// Two token buckets
|
||||
assertThat(policer.tokenBuckets().size(), is(2));
|
||||
// One token bucket equals to prTokenBucket
|
||||
assertTrue(policer.tokenBuckets().contains(prTokenBucket));
|
||||
// One token bucket equals to crTokenBucket
|
||||
assertTrue(policer.tokenBuckets().contains(crTokenBucket));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception expected to raise when creating a policer with null params.
|
||||
*/
|
||||
@Rule
|
||||
public ExpectedException exceptionNullParam = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Test creation with null parameters.
|
||||
*/
|
||||
@Test
|
||||
public void testNullParam() {
|
||||
// Define expected exception
|
||||
exceptionNullParam.expect(NullPointerException.class);
|
||||
// Invalid policer, device id is not defined
|
||||
DefaultPolicer.builder()
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID6)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception expected to raise when creating a policer without token buckets.
|
||||
*/
|
||||
@Rule
|
||||
public ExpectedException exceptionNoTokenBuckets = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Test creation without token buckets.
|
||||
*/
|
||||
@Test
|
||||
public void testNoTokenBuckets() {
|
||||
// Define expected exception
|
||||
exceptionNoTokenBuckets.expect(IllegalArgumentException.class);
|
||||
// Invalid policer, no token buckets
|
||||
DefaultPolicer.builder()
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID7)
|
||||
.forDeviceId(DID1)
|
||||
.withTokenBuckets(ImmutableList.of())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test equality between policers.
|
||||
*/
|
||||
@Test
|
||||
public void testEqualilty() {
|
||||
// Create a block traffic token bucket
|
||||
TokenBucket blockTokenBucket = DefaultTokenBucket.builder()
|
||||
.withBurstSize(0)
|
||||
.withAction(DROP)
|
||||
.build();
|
||||
// Create a mark traffic token bucket
|
||||
TokenBucket markTokenBucket = DefaultTokenBucket.builder()
|
||||
.withBurstSize(0)
|
||||
.withAction(DSCP_CLASS)
|
||||
.withDscp((short) 10)
|
||||
.build();
|
||||
// Create first policer
|
||||
Policer policerOne = DefaultPolicer.builder()
|
||||
.forDeviceId(DID1)
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID8)
|
||||
.withTokenBuckets(ImmutableList.of(blockTokenBucket))
|
||||
.build();
|
||||
// Create second policer
|
||||
Policer policerTwo = DefaultPolicer.builder()
|
||||
.forDeviceId(DID1)
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID9)
|
||||
.withTokenBuckets(ImmutableList.of(markTokenBucket))
|
||||
.build();
|
||||
// Create third policer copy of one
|
||||
// Create first policer
|
||||
Policer policerThree = DefaultPolicer.builder()
|
||||
.forDeviceId(DID1)
|
||||
.fromApp(FOO_APP_ID)
|
||||
.withId(ID8)
|
||||
.withTokenBuckets(ImmutableList.of(blockTokenBucket))
|
||||
.build();
|
||||
// One and Three are equal
|
||||
assertEquals(policerOne, policerThree);
|
||||
// Two is different due to the different id
|
||||
assertNotEquals(policerOne, policerTwo);
|
||||
assertNotEquals(policerThree, policerTwo);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.onlab.junit.ImmutableClassChecker;
|
||||
import org.onosproject.net.ConnectPoint;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test class for PolicingResource.
|
||||
*/
|
||||
public class PolicingResourceTest {
|
||||
|
||||
// Connectpoints
|
||||
private static final String SCP1 = "of:00000000000001/1";
|
||||
private static final String SCP2 = "of:00000000000001/2";
|
||||
private static final ConnectPoint CP1 = ConnectPoint.deviceConnectPoint(SCP1);
|
||||
private static final ConnectPoint CP2 = ConnectPoint.deviceConnectPoint(SCP2);
|
||||
// OpenFlow scheme
|
||||
private static final String OF_SCHEME = "of";
|
||||
// Policer identifier
|
||||
private static final String SID = OF_SCHEME + ":" + Integer.toHexString(1);
|
||||
private static final PolicerId PID = PolicerId.policerId(SID);
|
||||
|
||||
/**
|
||||
* Test policing resource creation.
|
||||
*/
|
||||
@Test
|
||||
public void testCreation() {
|
||||
// Create a new policing resource
|
||||
PolicingResource policingResource = new PolicingResource(PID, CP1);
|
||||
// Verify proper creation
|
||||
assertThat(policingResource, notNullValue());
|
||||
assertThat(policingResource.policerId(), is(PID));
|
||||
assertThat(policingResource.connectPoint(), is(CP1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception expected to raise when creating policing resource with null id.
|
||||
*/
|
||||
@Rule
|
||||
public ExpectedException exceptionNullId = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Test wrong creation of a policing resource.
|
||||
*/
|
||||
@Test
|
||||
public void testNullIdCreation() {
|
||||
// Define expected exception
|
||||
exceptionNullId.expect(NullPointerException.class);
|
||||
// Create wrong policing resource
|
||||
new PolicingResource(null, CP1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test equality between policing resources.
|
||||
*/
|
||||
@Test
|
||||
public void testEqualilty() {
|
||||
// Create two identical resources
|
||||
PolicingResource one = new PolicingResource(PID, CP1);
|
||||
PolicingResource copyOfOne = new PolicingResource(PID, CP1);
|
||||
// Verify equality
|
||||
assertEquals(one, copyOfOne);
|
||||
// Create a different resource
|
||||
PolicingResource two = new PolicingResource(PID, CP2);
|
||||
// Verify not equals
|
||||
assertNotEquals(two, one);
|
||||
assertNotEquals(two, copyOfOne);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests immutability of PolicingResource.
|
||||
*/
|
||||
@Test
|
||||
public void testImmutability() {
|
||||
ImmutableClassChecker.assertThatClassIsImmutable(PolicingResource.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.trafficcontrol;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.TokenBucket.Action.DROP;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.TokenBucket.Action.DSCP_CLASS;
|
||||
import static org.onosproject.net.behaviour.trafficcontrol.TokenBucket.Action.DSCP_PRECEDENCE;
|
||||
|
||||
/**
|
||||
* Test class for TokenBucket.
|
||||
*/
|
||||
public class TokenBucketTest {
|
||||
|
||||
// Test rate
|
||||
private static final long RATE = 1;
|
||||
// Test dscp drop precedence
|
||||
private static final short DSCP_PREC = 2;
|
||||
// Test dscp class
|
||||
private static final short DSCP_CL = 250;
|
||||
// Test wrong dscp
|
||||
private static final short WRONG_DSCP = -1;
|
||||
|
||||
/**
|
||||
* Test creation of a drop token bucket.
|
||||
*/
|
||||
@Test
|
||||
public void testDropCreation() {
|
||||
// Create a drop token bucket
|
||||
TokenBucket drop = DefaultTokenBucket.builder()
|
||||
.withRate(RATE)
|
||||
.withAction(DROP)
|
||||
.build();
|
||||
// Not null
|
||||
assertThat(drop, notNullValue());
|
||||
// Rate should be equal to RATE
|
||||
assertThat(drop.rate(), is(RATE));
|
||||
// Burst size should be equal to 2xMTU
|
||||
assertThat(drop.burstSize(), is(2 * 1500L));
|
||||
// Action should be drop
|
||||
assertThat(drop.action(), is(DROP));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation of a dscp precedence token bucket.
|
||||
*/
|
||||
@Test
|
||||
public void testDscpPrecCreation() {
|
||||
// Create a dscp precedence token bucket
|
||||
TokenBucket drop = DefaultTokenBucket.builder()
|
||||
.withRate(RATE)
|
||||
.withAction(DSCP_PRECEDENCE)
|
||||
.withBurstSize(6 * 1500)
|
||||
.withDscp(DSCP_PREC)
|
||||
.build();
|
||||
// Not null
|
||||
assertThat(drop, notNullValue());
|
||||
// Rate should be equal to RATE
|
||||
assertThat(drop.rate(), is(RATE));
|
||||
// Burst size should be equal to 6xMTU
|
||||
assertThat(drop.burstSize(), is(6 * 1500L));
|
||||
// Action should increase dscp drop precedence
|
||||
assertThat(drop.action(), is(DSCP_PRECEDENCE));
|
||||
// Dcsp drop precedence should be increased of 2
|
||||
assertThat(drop.dscp(), is(DSCP_PREC));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation of a dscp class token bucket.
|
||||
*/
|
||||
@Test
|
||||
public void testDscpClassCreation() {
|
||||
// Create a dscp class token bucket
|
||||
TokenBucket drop = DefaultTokenBucket.builder()
|
||||
.withRate(RATE)
|
||||
.withAction(DSCP_CLASS)
|
||||
.withDscp(DSCP_CL)
|
||||
.build();
|
||||
// Not null
|
||||
assertThat(drop, notNullValue());
|
||||
// Rate should be equal to RATE
|
||||
assertThat(drop.rate(), is(RATE));
|
||||
// Burst size should be equal to 2xMTU
|
||||
assertThat(drop.burstSize(), is(2 * 1500L));
|
||||
// Action should be drop
|
||||
assertThat(drop.action(), is(DSCP_CLASS));
|
||||
// Dcsp drop precedence should be increased of 2
|
||||
assertThat(drop.dscp(), is(DSCP_CL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception expected to raise when creating a token bucket with null action.
|
||||
*/
|
||||
@Rule
|
||||
public ExpectedException exceptionNullAction = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Test creation of a token bucket with null action.
|
||||
*/
|
||||
@Test
|
||||
public void testNullActionCreation() {
|
||||
// Define expected exception
|
||||
exceptionNullAction.expect(NullPointerException.class);
|
||||
// Create a token bucket without action
|
||||
TokenBucket drop = DefaultTokenBucket.builder()
|
||||
.withRate(RATE)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception expected to raise when creating a token bucket with wrong dscp.
|
||||
*/
|
||||
@Rule
|
||||
public ExpectedException exceptionWrongDscp = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Test creation of a token bucket with wrong dscp.
|
||||
*/
|
||||
@Test
|
||||
public void testWrongDscpCreation() {
|
||||
// Define expected exception
|
||||
exceptionWrongDscp.expect(IllegalArgumentException.class);
|
||||
// Create a token bucket with wrong dscp
|
||||
TokenBucket drop = DefaultTokenBucket.builder()
|
||||
.withRate(RATE)
|
||||
.withAction(DSCP_PRECEDENCE)
|
||||
.withDscp(WRONG_DSCP)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test equality between policer ids.
|
||||
*/
|
||||
@Test
|
||||
public void testEqualilty() {
|
||||
// Create a drop token bucket
|
||||
TokenBucket drop = DefaultTokenBucket.builder()
|
||||
.withRate(RATE)
|
||||
.withAction(DROP)
|
||||
.build();
|
||||
// Create a mark token bucket
|
||||
TokenBucket mark = DefaultTokenBucket.builder()
|
||||
.withRate(RATE)
|
||||
.withAction(DSCP_PRECEDENCE)
|
||||
.withDscp(DSCP_PREC)
|
||||
.build();
|
||||
// Create a copy of the drop token bucket
|
||||
TokenBucket copyDrop = DefaultTokenBucket.builder()
|
||||
.withRate(RATE)
|
||||
.withAction(DROP)
|
||||
.build();
|
||||
// Verify equality
|
||||
assertEquals(drop, copyDrop);
|
||||
// Verify not equals
|
||||
assertNotEquals(mark, drop);
|
||||
assertNotEquals(mark, copyDrop);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2017-present Open Networking Foundation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test class for traffic control behaviors and related classes.
|
||||
*/
|
||||
package org.onosproject.net.behaviour.trafficcontrol;
|
Loading…
x
Reference in New Issue
Block a user