Add slice meter to upf programmable driver behaviour
Also, TC in terminations entities is now required when not dropping.
Change-Id: Ia7e371376ca4f61564ba52a1e8c85a0ff76bb202
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntityType.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntityType.java
index c5d5590..07890f7 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntityType.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntityType.java
@@ -32,7 +32,10 @@
COUNTER("counter"),
APPLICATION("application"),
SESSION_METER("session_meter"),
- APPLICATION_METER("application_meter");
+ APPLICATION_METER("application_meter"),
+ // TODO: slice meter shouldn't be exposed via UpfProgrammable driver behaviour
+ // we should have dedicated driver behaviour for the slicing functionality.
+ SLICE_METER("slice_meter");
private final String humanReadableName;
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfMeter.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfMeter.java
index 1a3e799..39302eb 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfMeter.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfMeter.java
@@ -16,6 +16,7 @@
package org.onosproject.net.behaviour.upf;
+import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.onosproject.net.meter.Band;
@@ -29,16 +30,18 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.behaviour.upf.UpfEntityType.APPLICATION_METER;
import static org.onosproject.net.behaviour.upf.UpfEntityType.SESSION_METER;
+import static org.onosproject.net.behaviour.upf.UpfEntityType.SLICE_METER;
import static org.onosproject.net.meter.Band.Type.MARK_RED;
import static org.onosproject.net.meter.Band.Type.MARK_YELLOW;
/**
- * A structure representing a UPF meter, either for metering session (UE) or
- * application traffic.
- * UPF meters represent PFCP QER MBR and GBR information.
- * UPF meters of type session support only the peak band.
+ * A structure representing a UPF meter, either for metering session (UE),
+ * application traffic, or slice traffic.
+ * UPF meters represent PFCP QER MBR and GBR information and slice maximum rate.
+ * UPF meters of type session and slice support only the peak band.
* UPF meters of type application support both peak and committed bands.
*/
+@Beta
public final class UpfMeter implements UpfEntity {
private final int cellId;
private final ImmutableMap<Band.Type, Band> meterBands;
@@ -161,13 +164,24 @@
return new UpfMeter(cellId, Maps.newHashMap(), APPLICATION_METER);
}
+ /**
+ * Return a slice meter with no bands. Used to reset the meter.
+ *
+ * @param cellId the meter cell index of this meter
+ * @return a UpfMeter of type slice with no bands
+ */
+ public static UpfMeter resetSlice(int cellId) {
+ return new UpfMeter(cellId, Maps.newHashMap(), SLICE_METER);
+ }
+
public static Builder builder() {
return new Builder();
}
/**
- * Builder of UpfMeter object. Use {@link #resetApplication(int)} and
- * {@link #resetSession(int)} to reset the meter config.
+ * Builder of UpfMeter object. Use {@link #resetApplication(int)},
+ * {@link #resetSession(int)}, or {@link #resetSlice(int)} to reset the
+ * meter config.
*/
public static class Builder {
private Integer cellId = null;
@@ -246,12 +260,23 @@
return this;
}
+ /**
+ * Make this meter a slice meter.
+ *
+ * @return this builder object
+ */
+ public Builder setSlice() {
+ this.type = SLICE_METER;
+ return this;
+ }
+
public UpfMeter build() {
checkNotNull(type, "A meter type must be assigned");
switch (type) {
case SESSION_METER:
+ case SLICE_METER:
checkArgument(!bands.containsKey(MARK_YELLOW),
- "Committed band can not be provided for session meter!");
+ "Committed band can not be provided for " + type + " meter!");
break;
case APPLICATION_METER:
checkArgument((bands.containsKey(MARK_YELLOW) && bands.containsKey(MARK_RED)) || bands.isEmpty(),
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationDownlink.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationDownlink.java
index dd66724..22c25c0 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationDownlink.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationDownlink.java
@@ -297,6 +297,9 @@
applicationId = DEFAULT_APP_ID;
}
checkNotNull(ctrId, "Counter ID must be provided");
+ if (!drop) {
+ checkNotNull(trafficClass, "Traffic class must be provided");
+ }
// TODO: should we verify that when dropping no other fields are provided
return new UpfTerminationDownlink(
this.ueSessionId, this.applicationId, this.ctrId, this.trafficClass,
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationUplink.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationUplink.java
index ddec2e4..4584858 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationUplink.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationUplink.java
@@ -248,6 +248,9 @@
applicationId = DEFAULT_APP_ID;
}
checkNotNull(ctrId, "Counter ID must be provided");
+ if (!dropping) {
+ checkNotNull(trafficClass, "Traffic class must be provided");
+ }
// TODO: should we verify that when dropping no other fields are provided
return new UpfTerminationUplink(
this.ueSessionId, this.applicationId, this.ctrId,