[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
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/DefaultPolicer.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/DefaultPolicer.java
new file mode 100644
index 0000000..d375f9d
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/DefaultPolicer.java
@@ -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);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/DefaultTokenBucket.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/DefaultTokenBucket.java
new file mode 100644
index 0000000..f3920b2
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/DefaultTokenBucket.java
@@ -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);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/Policer.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/Policer.java
new file mode 100644
index 0000000..af17050
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/Policer.java
@@ -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();
+ }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicerEntry.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicerEntry.java
new file mode 100644
index 0000000..0f019ef
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicerEntry.java
@@ -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);
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicerId.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicerId.java
new file mode 100644
index 0000000..c373dbe
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicerId.java
@@ -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;
+ }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicingResource.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicingResource.java
new file mode 100644
index 0000000..29ab258
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/PolicingResource.java
@@ -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);
+ }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/TokenBucket.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/TokenBucket.java
new file mode 100644
index 0000000..a86466b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/TokenBucket.java
@@ -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();
+
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/TokenBucketEntry.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/TokenBucketEntry.java
new file mode 100644
index 0000000..00ca270
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/TokenBucketEntry.java
@@ -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);
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/package-info.java b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/package-info.java
new file mode 100644
index 0000000..188f3de
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/trafficcontrol/package-info.java
@@ -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;