[SDFAB-831] Add UPF meters to UpfProgrammable APIs
UPF meters can be of type session or application.
Also, add meter index to sessions and terminations UPF entities.
Change-Id: I8babfca35341a21b234d8eb6edaa2e1c02684210
(cherry picked from commit b25299afaf824a8d352297224e5b9a1285901d00)
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntity.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntity.java
index 81dd28a..e54ab34 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntity.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntity.java
@@ -29,6 +29,16 @@
byte DEFAULT_APP_ID = 0;
/**
+ * Default session index, to be used if no session metering is performed.
+ */
+ int DEFAULT_SESSION_INDEX = 0;
+
+ /**
+ * Default app index, to be used if no app metering is performed.
+ */
+ int DEFAULT_APP_INDEX = 0;
+
+ /**
* Returns the type of this entity.
*
* @return entity type
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 2e9a26a..c5d5590 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
@@ -30,7 +30,9 @@
SESSION_UPLINK("session_downlink"),
TUNNEL_PEER("tunnel_peer"),
COUNTER("counter"),
- APPLICATION("application");
+ APPLICATION("application"),
+ SESSION_METER("session_meter"),
+ APPLICATION_METER("application_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
new file mode 100644
index 0000000..1a3e799
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfMeter.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2022-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.upf;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkArgument;
+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.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.
+ * UPF meters of type application support both peak and committed bands.
+ */
+public final class UpfMeter implements UpfEntity {
+ private final int cellId;
+ private final ImmutableMap<Band.Type, Band> meterBands;
+ private final UpfEntityType type;
+
+ private UpfMeter(int cellId, Map<Band.Type, Band> meterBands, UpfEntityType type) {
+ this.cellId = cellId;
+ this.meterBands = ImmutableMap.copyOf(meterBands);
+ this.type = type;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("UpfMeter(type=%s, index=%d, committed=%s, peak=%s)",
+ type, cellId, committedBand().orElse(null),
+ peakBand().orElse(null));
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+
+ if (object == null) {
+ return false;
+ }
+
+ if (getClass() != object.getClass()) {
+ return false;
+ }
+
+ UpfMeter that = (UpfMeter) object;
+ return this.type.equals(that.type) &&
+ this.cellId == that.cellId &&
+ this.meterBands.equals(that.meterBands);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, cellId, meterBands);
+ }
+
+ @Override
+ public UpfEntityType type() {
+ return this.type;
+ }
+
+ /**
+ * Get the meter cell index of this meter.
+ *
+ * @return the cell index
+ */
+ public int cellId() {
+ return this.cellId;
+ }
+
+ /**
+ * Get the committed band of this meter.
+ *
+ * @return the committed band, Empty if none
+ */
+ public Optional<Band> committedBand() {
+ return Optional.ofNullable(meterBands.getOrDefault(MARK_YELLOW, null));
+ }
+
+ /**
+ * Get the peak band of this meter.
+ *
+ * @return the peak band, Empty if none
+ */
+ public Optional<Band> peakBand() {
+ return Optional.ofNullable(meterBands.getOrDefault(MARK_RED, null));
+ }
+
+ /**
+ * Check if this UPF meter is for sessions (UE) traffic.
+ *
+ * @return true if the meter is for session traffic
+ */
+ public boolean isSession() {
+ return type.equals(SESSION_METER);
+ }
+
+ /**
+ * Check if this UPF meter is for application traffic.
+ *
+ * @return true if the meter is for application traffic
+ */
+ public boolean isApplication() {
+ return type.equals(APPLICATION_METER);
+ }
+
+ /**
+ * Check if this UPF meter is a reset.
+ *
+ * @return true if this represents a meter reset.
+ */
+ public boolean isReset() {
+ return meterBands.isEmpty();
+ }
+
+ /**
+ * Return a session UPF meter with no bands. Used to reset the meter.
+ *
+ * @param cellId the meter cell index of this meter
+ * @return a UpfMeter of type session with no bands
+ */
+ public static UpfMeter resetSession(int cellId) {
+ return new UpfMeter(cellId, Maps.newHashMap(), SESSION_METER);
+ }
+
+ /**
+ * Return an application UPF meter with no bands. Used to reset the meter.
+ *
+ * @param cellId the meter cell index of this meter
+ * @return a UpfMeter of type application with no bands
+ */
+ public static UpfMeter resetApplication(int cellId) {
+ return new UpfMeter(cellId, Maps.newHashMap(), APPLICATION_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.
+ */
+ public static class Builder {
+ private Integer cellId = null;
+ private Map<Band.Type, Band> bands = Maps.newHashMap();
+ private UpfEntityType type;
+
+ public Builder() {
+
+ }
+
+ /**
+ * Set the meter cell index of this meter.
+ *
+ * @param cellId the meter cell index
+ * @return this builder object
+ */
+ public Builder setCellId(int cellId) {
+ this.cellId = cellId;
+ return this;
+ }
+
+ /**
+ * Set the committed band of this meter.
+ * Valid only for meter of type application.
+ *
+ * @param cir the Committed Information Rate in bytes/s
+ * @param cburst the Committed Burst in bytes
+ * @return this builder object
+ */
+ public Builder setCommittedBand(long cir, long cburst) {
+ this.bands.put(MARK_YELLOW,
+ DefaultBand.builder()
+ .ofType(MARK_YELLOW)
+ .withRate(cir)
+ .burstSize(cburst)
+ .build()
+ );
+ return this;
+ }
+
+ /**
+ * Set the peak band of this meter.
+ *
+ * @param pir the Peak Information Rate in bytes/s
+ * @param pburst the Peak Burst in bytes
+ * @return this builder object
+ */
+ public Builder setPeakBand(long pir, long pburst) {
+ this.bands.put(MARK_RED,
+ DefaultBand.builder()
+ .ofType(MARK_RED)
+ .withRate(pir)
+ .burstSize(pburst)
+ .build()
+ );
+ return this;
+ }
+
+ /**
+ * Make this meter a session meter.
+ *
+ * @return this builder object
+ */
+ public Builder setSession() {
+ this.type = SESSION_METER;
+ return this;
+ }
+
+ /**
+ * Make this meter an application meter.
+ *
+ * @return this builder object
+ */
+ public Builder setApplication() {
+ this.type = APPLICATION_METER;
+ return this;
+ }
+
+ public UpfMeter build() {
+ checkNotNull(type, "A meter type must be assigned");
+ switch (type) {
+ case SESSION_METER:
+ checkArgument(!bands.containsKey(MARK_YELLOW),
+ "Committed band can not be provided for session meter!");
+ break;
+ case APPLICATION_METER:
+ checkArgument((bands.containsKey(MARK_YELLOW) && bands.containsKey(MARK_RED)) || bands.isEmpty(),
+ "Bands (committed and peak) must be provided together or not at all!");
+ break;
+ default:
+ // I should never reach this point
+ throw new IllegalArgumentException("Invalid meter type, I should never reach this point");
+ }
+ checkNotNull(cellId, "Meter cell ID must be provided!");
+ return new UpfMeter(cellId, bands, type);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfProgrammable.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfProgrammable.java
index 052084e..2fd718c 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfProgrammable.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfProgrammable.java
@@ -19,6 +19,7 @@
import com.google.common.annotations.Beta;
import org.onosproject.net.driver.HandlerBehaviour;
import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.meter.Meter;
/**
* Provides means to update the device forwarding state to implement a 3GPP
@@ -43,4 +44,12 @@
* @return True if the given flow rule has been created by this UPF behaviour, False otherwise.
*/
boolean fromThisUpf(FlowRule flowRule);
+
+ /**
+ * Checks if the given meter has been generated by this UPF behaviour.
+ *
+ * @param meter the meter to check
+ * @return True if the given meter has been created by this UPF behaviour, False otherwise.
+ */
+ boolean fromThisUpf(Meter meter);
}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfSessionDownlink.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfSessionDownlink.java
index 413c7ed..02a8a54 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfSessionDownlink.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfSessionDownlink.java
@@ -33,14 +33,17 @@
private final Ip4Address ueAddress;
// Action parameters
private final Byte tunPeerId;
+ private final int sessionMeterIdx;
private final boolean buffering;
private final boolean dropping;
private UpfSessionDownlink(Ip4Address ipv4Address,
Byte tunPeerId,
+ int sessionMeterIdx,
boolean buffering,
boolean drop) {
this.ueAddress = ipv4Address;
+ this.sessionMeterIdx = sessionMeterIdx;
this.tunPeerId = tunPeerId;
this.buffering = buffering;
this.dropping = drop;
@@ -66,13 +69,14 @@
return this.buffering == that.buffering &&
this.dropping == that.dropping &&
+ this.sessionMeterIdx == that.sessionMeterIdx &&
Objects.equals(ueAddress, that.ueAddress) &&
Objects.equals(tunPeerId, that.tunPeerId);
}
@Override
public int hashCode() {
- return java.util.Objects.hash(ueAddress, tunPeerId, buffering, dropping);
+ return java.util.Objects.hash(ueAddress, sessionMeterIdx, tunPeerId, buffering, dropping);
}
@Override
@@ -95,7 +99,8 @@
} else {
actionStrBuilder.append("FWD, ");
}
- return actionStrBuilder.append(" tun_peer=").append(this.tunPeerId()).append(")")
+ return actionStrBuilder.append(" tun_peer=").append(this.tunPeerId())
+ .append(", session_meter_idx=").append(this.sessionMeterIdx()).append(")")
.toString();
}
@@ -135,6 +140,15 @@
return tunPeerId;
}
+ /**
+ * Get the session meter index that is set by this UPF UE Session rule.
+ *
+ * @return Session meter index
+ */
+ public int sessionMeterIdx() {
+ return this.sessionMeterIdx;
+ }
+
@Override
public UpfEntityType type() {
return UpfEntityType.SESSION_DOWNLINK;
@@ -143,6 +157,7 @@
public static class Builder {
private Ip4Address ueAddress = null;
private Byte tunPeerId = null;
+ private int sessionMeterIdx = DEFAULT_SESSION_INDEX;
private boolean buffer = false;
private boolean drop = false;
@@ -151,7 +166,7 @@
}
/**
- * Set the UE IP address that this downlink UPF UE session rule matches on.
+ * Sets the UE IP address that this downlink UPF UE session rule matches on.
*
* @param ueAddress UE IP address
* @return This builder object
@@ -162,7 +177,7 @@
}
/**
- * Set the GTP tunnel peer ID that is set by this UPF UE Session rule.
+ * Sets the GTP tunnel peer ID that is set by this UPF UE Session rule.
*
* @param tunnelPeerId GTP tunnel peer ID
* @return This builder object
@@ -173,7 +188,7 @@
}
/**
- * Set whether to buffer downlink UPF UE session traffic or not.
+ * Sets whether to buffer downlink UPF UE session traffic or not.
*
* @param buffer True if request to buffer, false otherwise
* @return This builder object
@@ -184,7 +199,7 @@
}
/**
- * Set whether to drop downlink UPF UE session traffic or not.
+ * Sets whether to drop downlink UPF UE session traffic or not.
*
* @param drop True if request to buffer, false otherwise
* @return This builder object
@@ -194,10 +209,22 @@
return this;
}
+ /**
+ * Sets the meter index associated with this UE session.
+ * If not set, default to {@link UpfEntity#DEFAULT_SESSION_INDEX}.
+ *
+ * @param sessionMeterIdx Session meter index
+ * @return This builder object
+ */
+ public Builder withSessionMeterIdx(int sessionMeterIdx) {
+ this.sessionMeterIdx = sessionMeterIdx;
+ return this;
+ }
+
public UpfSessionDownlink build() {
// Match fields are required
checkNotNull(ueAddress, "UE address must be provided");
- return new UpfSessionDownlink(ueAddress, tunPeerId, buffer, drop);
+ return new UpfSessionDownlink(ueAddress, tunPeerId, sessionMeterIdx, buffer, drop);
}
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfSessionUplink.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfSessionUplink.java
index 0a6bfa4..7cdff7e 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfSessionUplink.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfSessionUplink.java
@@ -35,12 +35,15 @@
// Action parameters
private final boolean dropping; // Used to convey dropping information
+ private final int sessionMeterIdx;
private UpfSessionUplink(Ip4Address tunDestAddr,
Integer teid,
+ int sessionMeterIdx,
boolean drop) {
this.tunDestAddr = tunDestAddr;
this.teid = teid;
+ this.sessionMeterIdx = sessionMeterIdx;
this.dropping = drop;
}
@@ -63,13 +66,14 @@
UpfSessionUplink that = (UpfSessionUplink) object;
return this.dropping == that.dropping &&
+ this.sessionMeterIdx == that.sessionMeterIdx &&
Objects.equals(tunDestAddr, that.tunDestAddr) &&
Objects.equals(teid, that.teid);
}
@Override
public int hashCode() {
- return Objects.hash(tunDestAddr, teid, dropping);
+ return Objects.hash(tunDestAddr, teid, sessionMeterIdx, dropping);
}
@Override
@@ -89,7 +93,9 @@
} else {
actionStrBuilder.append("FWD");
}
- return actionStrBuilder.append(")").toString();
+ return actionStrBuilder
+ .append(", session_meter_idx=").append(this.sessionMeterIdx())
+ .append(")").toString();
}
/**
@@ -119,6 +125,15 @@
return teid;
}
+ /**
+ * Get the session meter index that is set by this UPF UE Session rule.
+ *
+ * @return Session meter index
+ */
+ public int sessionMeterIdx() {
+ return this.sessionMeterIdx;
+ }
+
@Override
public UpfEntityType type() {
return UpfEntityType.SESSION_UPLINK;
@@ -127,6 +142,7 @@
public static class Builder {
private Ip4Address tunDstAddr = null;
private Integer teid = null;
+ public int sessionMeterIdx = DEFAULT_SESSION_INDEX;
private boolean drop = false;
public Builder() {
@@ -134,7 +150,7 @@
}
/**
- * Set the tunnel destination IP address (N3/S1U address) that this UPF UE Session rule matches on.
+ * Sets the tunnel destination IP address (N3/S1U address) that this UPF UE Session rule matches on.
*
* @param tunDstAddr The tunnel destination IP address
* @return This builder object
@@ -145,7 +161,7 @@
}
/**
- * Set the identifier of the GTP tunnel that this UPF UE Session rule matches on.
+ * Sets the identifier of the GTP tunnel that this UPF UE Session rule matches on.
*
* @param teid GTP tunnel ID
* @return This builder object
@@ -167,11 +183,23 @@
return this;
}
+ /**
+ * Sets the meter index associated with this UE session.
+ * If not set, default to {@link UpfEntity#DEFAULT_SESSION_INDEX}.
+ *
+ * @param sessionMeterIdx Session meter index
+ * @return This builder object
+ */
+ public Builder withSessionMeterIdx(int sessionMeterIdx) {
+ this.sessionMeterIdx = sessionMeterIdx;
+ return this;
+ }
+
public UpfSessionUplink build() {
// Match keys are required.
checkNotNull(tunDstAddr, "Tunnel destination must be provided");
checkNotNull(teid, "TEID must be provided");
- return new UpfSessionUplink(tunDstAddr, teid, drop);
+ return new UpfSessionUplink(tunDstAddr, teid, sessionMeterIdx, drop);
}
}
}
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 edab0ac..dd66724 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
@@ -38,16 +38,18 @@
private final Byte trafficClass;
private final Integer teid; // Tunnel Endpoint Identifier
private final Byte qfi; // QoS Flow Identifier
+ private final int appMeterIdx;
private final boolean dropping;
private UpfTerminationDownlink(Ip4Address ueSessionId, byte applicationId, Integer ctrId, Byte trafficClass,
- Integer teid, Byte qfi, boolean dropping) {
+ Integer teid, Byte qfi, int appMeterIdx, boolean dropping) {
this.ueSessionId = ueSessionId;
this.applicationId = applicationId;
this.ctrId = ctrId;
this.trafficClass = trafficClass;
this.teid = teid;
this.qfi = qfi;
+ this.appMeterIdx = appMeterIdx;
this.dropping = dropping;
}
@@ -75,12 +77,13 @@
Objects.equals(this.ctrId, that.ctrId) &&
Objects.equals(this.trafficClass, that.trafficClass) &&
Objects.equals(this.teid, that.teid) &&
+ this.appMeterIdx == that.appMeterIdx &&
Objects.equals(this.qfi, that.qfi);
}
@Override
public int hashCode() {
- return Objects.hash(ueSessionId, applicationId, ctrId, trafficClass, teid, qfi, dropping);
+ return Objects.hash(ueSessionId, applicationId, ctrId, trafficClass, teid, qfi, appMeterIdx, dropping);
}
/**
@@ -146,6 +149,15 @@
return dropping;
}
+ /**
+ * Get the app meter index set by this UPF Termination rule.
+ *
+ * @return App meter index
+ */
+ public int appMeterIdx() {
+ return appMeterIdx;
+ }
+
@Override
public UpfEntityType type() {
return UpfEntityType.TERMINATION_DOWNLINK;
@@ -170,6 +182,7 @@
", ctr_id=" + this.counterId() +
", qfi=" + this.qfi() +
", tc=" + this.trafficClass() +
+ ", app_meter_idx=" + this.appMeterIdx() +
")";
}
@@ -180,6 +193,7 @@
private Byte trafficClass = null;
private Integer teid = null;
private Byte qfi = null;
+ private int appMeterIdx = DEFAULT_APP_INDEX;
private boolean drop = false;
public Builder() {
@@ -199,6 +213,7 @@
/**
* Set the ID of the application.
+ * If not set, default to {@link UpfEntity#DEFAULT_APP_ID}.
*
* @param applicationId Application ID
* @return This builder object
@@ -263,6 +278,18 @@
return this;
}
+ /**
+ * Sets the app meter index.
+ * If not set, default to {@link UpfEntity#DEFAULT_APP_INDEX}.
+ *
+ * @param appMeterIdx App meter index
+ * @return This builder object
+ */
+ public Builder withAppMeterIdx(int appMeterIdx) {
+ this.appMeterIdx = appMeterIdx;
+ return this;
+ }
+
public UpfTerminationDownlink build() {
// Match fields must be provided
checkNotNull(ueSessionId, "UE session ID must be provided");
@@ -273,7 +300,7 @@
// TODO: should we verify that when dropping no other fields are provided
return new UpfTerminationDownlink(
this.ueSessionId, this.applicationId, this.ctrId, this.trafficClass,
- this.teid, this.qfi, this.drop
+ this.teid, this.qfi, this.appMeterIdx, this.drop
);
}
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 93ac0b7..ddec2e4 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
@@ -36,14 +36,17 @@
// Action parameters
private final Integer ctrId; // Counter ID unique to this UPF Termination Rule
private final Byte trafficClass;
+ private final int appMeterIdx;
private final boolean dropping;
- private UpfTerminationUplink(Ip4Address ueSessionId, byte applicationId, Integer ctrId, Byte trafficClass,
- boolean dropping) {
+ private UpfTerminationUplink(Ip4Address ueSessionId, byte applicationId,
+ Integer ctrId, Byte trafficClass,
+ int appMeterIdx, boolean dropping) {
this.ueSessionId = ueSessionId;
this.applicationId = applicationId;
this.ctrId = ctrId;
this.trafficClass = trafficClass;
+ this.appMeterIdx = appMeterIdx;
this.dropping = dropping;
}
@@ -69,12 +72,13 @@
Objects.equals(this.ueSessionId, that.ueSessionId) &&
Objects.equals(this.applicationId, that.applicationId) &&
Objects.equals(this.ctrId, that.ctrId) &&
+ this.appMeterIdx == that.appMeterIdx &&
Objects.equals(this.trafficClass, that.trafficClass);
}
@Override
public int hashCode() {
- return Objects.hash(ueSessionId, applicationId, ctrId, trafficClass, dropping);
+ return Objects.hash(ueSessionId, applicationId, ctrId, trafficClass, appMeterIdx, dropping);
}
/**
@@ -122,6 +126,15 @@
return dropping;
}
+ /**
+ * Get the app meter index set by this UPF Termination rule.
+ *
+ * @return App meter index
+ */
+ public int appMeterIdx() {
+ return appMeterIdx;
+ }
+
@Override
public UpfEntityType type() {
return UpfEntityType.TERMINATION_UPLINK;
@@ -144,6 +157,7 @@
return "Action(" + fwd +
", ctr_id=" + this.counterId() +
", tc=" + this.trafficClass() +
+ ", app_meter_idx=" + this.appMeterIdx() +
")";
}
@@ -152,6 +166,7 @@
private Byte applicationId = null;
private Integer ctrId = null;
private Byte trafficClass = null;
+ private int appMeterIdx = DEFAULT_APP_INDEX;
private boolean dropping = false;
public Builder() {
@@ -171,6 +186,7 @@
/**
* Set the ID of the application.
+ * If not set, default to {@link UpfEntity#DEFAULT_APP_ID}.
*
* @param applicationId Application ID
* @return This builder object
@@ -213,6 +229,18 @@
return this;
}
+ /**
+ * Sets the app meter index.
+ * If not set, default to {@link UpfEntity#DEFAULT_APP_INDEX}.
+ *
+ * @param appMeterIdx App meter index
+ * @return This builder object
+ */
+ public Builder withAppMeterIdx(int appMeterIdx) {
+ this.appMeterIdx = appMeterIdx;
+ return this;
+ }
+
public UpfTerminationUplink build() {
// Match fields must be provided
checkNotNull(ueSessionId, "UE session ID must be provided");
@@ -223,7 +251,7 @@
// TODO: should we verify that when dropping no other fields are provided
return new UpfTerminationUplink(
this.ueSessionId, this.applicationId, this.ctrId,
- this.trafficClass, this.dropping
+ this.trafficClass, this.appMeterIdx, this.dropping
);
}
diff --git a/core/api/src/main/java/org/onosproject/net/meter/DefaultBand.java b/core/api/src/main/java/org/onosproject/net/meter/DefaultBand.java
index e0069a5..85e6c70 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/DefaultBand.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/DefaultBand.java
@@ -15,6 +15,8 @@
*/
package org.onosproject.net.meter;
+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;
@@ -96,6 +98,26 @@
return new Builder();
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ DefaultBand that = (DefaultBand) o;
+ return rate == that.rate &&
+ type == that.type &&
+ Objects.equal(burstSize, that.burstSize) &&
+ Objects.equal(prec, that.prec);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(type, rate, burstSize, prec);
+ }
+
public static final class Builder implements Band.Builder {
private long rate;