[SDFAB-357] Backport slicing in fabric and add support for QFI in PDR and fabric
Change-Id: Ieb10140dc0029a0cbf59ddfbb77f64f9a8c7379e
(cherry picked from commit 411f6f7f461db6491d627c2cb31642bdd6e7c8d8)
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/ForwardingActionRule.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/ForwardingActionRule.java
index 3cd7c8c..bfed1ce 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/ForwardingActionRule.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/ForwardingActionRule.java
@@ -86,7 +86,8 @@
} else if (tunnel != null) {
actionName = "Encap";
actionParams = String.format("Src=%s, SPort=%d, TEID=%s, Dst=%s",
- tunnel.src().toString(), tunnel.srcPort(), tunnel.teid().toString(), tunnel.dst().toString());
+ tunnel.src().toString(), tunnel.srcPort(),
+ tunnel.teid().toString(), tunnel.dst().toString());
} else {
actionName = "Forward";
}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/PacketDetectionRule.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/PacketDetectionRule.java
index c2069a5..f607d87 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/PacketDetectionRule.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/PacketDetectionRule.java
@@ -43,22 +43,27 @@
private final Integer ctrId; // Counter ID unique to this PDR
private final Integer farId; // The PFCP session-local ID of the FAR that should apply after this PDR hits
private final Type type;
- private final Integer schedulingPriority;
+
+ private final Byte qfi; // QoS Flow Identifier of this PDR
+ private final boolean qfiPush; // True when QFI should be pushed to the packet
+ private final boolean qfiMatch; // True when QFI should be matched
private static final int SESSION_ID_BITWIDTH = 96;
private PacketDetectionRule(ImmutableByteSequence sessionId, Integer ctrId,
- Integer farId, Integer schedulingPriority,
- Ip4Address ueAddr, ImmutableByteSequence teid,
- Ip4Address tunnelDst, Type type) {
+ Integer farId, Ip4Address ueAddr, Byte qfi,
+ ImmutableByteSequence teid, Ip4Address tunnelDst,
+ Type type, boolean qfiPush, boolean qfiMatch) {
this.ueAddr = ueAddr;
this.teid = teid;
this.tunnelDst = tunnelDst;
this.sessionId = sessionId;
this.ctrId = ctrId;
this.farId = farId;
- this.schedulingPriority = schedulingPriority;
+ this.qfi = qfi;
this.type = type;
+ this.qfiPush = qfiPush;
+ this.qfiMatch = qfiMatch;
}
public static Builder builder() {
@@ -72,7 +77,9 @@
*/
public String matchString() {
if (matchesEncapped()) {
- return String.format("Match(Dst=%s, TEID=%s)", tunnelDest(), teid());
+ return matchQfi() ?
+ String.format("Match(Dst=%s, TEID=%s, QFI=%s)", tunnelDest(), teid(), qfi()) :
+ String.format("Match(Dst=%s, TEID=%s)", tunnelDest(), teid());
} else {
return String.format("Match(Dst=%s, !GTP)", ueAddress());
}
@@ -82,8 +89,12 @@
public String toString() {
String actionParams = "";
if (hasActionParameters()) {
- actionParams = String.format("SEID=%s, FAR=%d, CtrIdx=%d, SchedulingPrio=%d",
- sessionId.toString(), farId, ctrId, schedulingPriority);
+ actionParams = hasQfi() && !matchQfi() ?
+ String.format("SEID=%s, FAR=%d, CtrIdx=%d, QFI=%s",
+ sessionId.toString(), farId, ctrId, qfi) :
+ String.format("SEID=%s, FAR=%d, CtrIdx=%d",
+ sessionId.toString(), farId, ctrId);
+ actionParams = pushQfi() ? String.format("%s, QFI_PUSH", actionParams) : actionParams;
}
return String.format("PDR{%s -> LoadParams(%s)}",
@@ -111,13 +122,15 @@
Objects.equals(this.ctrId, that.ctrId) &&
Objects.equals(this.sessionId, that.sessionId) &&
Objects.equals(this.farId, that.farId) &&
- Objects.equals(this.schedulingPriority, that.schedulingPriority));
+ Objects.equals(this.qfi, that.qfi) &&
+ Objects.equals(this.qfiPush, that.qfiPush) &&
+ Objects.equals(this.qfiMatch, that.qfiMatch));
}
@Override
public int hashCode() {
return Objects.hash(ueAddr, teid, tunnelDst, sessionId, ctrId, farId,
- schedulingPriority, type);
+ qfi, type);
}
/**
@@ -139,10 +152,14 @@
*/
public PacketDetectionRule withoutActionParams() {
if (matchesEncapped()) {
- return PacketDetectionRule.builder()
+ PacketDetectionRule.Builder pdrBuilder = PacketDetectionRule.builder()
.withTeid(teid)
- .withTunnelDst(tunnelDst)
- .build();
+ .withTunnelDst(tunnelDst);
+ if (this.hasQfi() && this.matchQfi()) {
+ pdrBuilder.withQfiMatch();
+ pdrBuilder.withQfi(qfi);
+ }
+ return pdrBuilder.build();
} else {
return PacketDetectionRule.builder()
.withUeAddr(ueAddr).build();
@@ -227,22 +244,39 @@
}
/**
- * Get the scheduling priority that this PDR is assigned.
+ * Get the QoS Flow Identifier for this PDR.
*
- * @return scheduling priority
+ * @return QoS Flow Identifier
*/
- public int schedulingPriority() {
- return schedulingPriority;
+ public byte qfi() {
+ return qfi;
}
/**
- * This method is used to differentiate between prioritized and non-prioritized
- * flows.
+ * Returns whether QFi should be pushed to the packet.
*
- * @return true if scheduling priority is assigned.
+ * @return True if the QFI should be pushed to the packet, false otherwise
*/
- public boolean hasSchedulingPriority() {
- return schedulingPriority > 0;
+ public boolean pushQfi() {
+ return qfiPush;
+ }
+
+ /**
+ * Returns whether QFI should be matched on the packet or not.
+ *
+ * @return True if QFI should be matched on the packet, false otherwise
+ */
+ public boolean matchQfi() {
+ return qfiMatch;
+ }
+
+ /**
+ * Checks if the PDR has a QFI to match upon or to push on the packet.
+ *
+ * @return True if the PDR has a QFI, false otherwise
+ */
+ public boolean hasQfi() {
+ return qfi != null;
}
private enum Type {
@@ -276,6 +310,9 @@
private Ip4Address ueAddr = null;
private ImmutableByteSequence teid = null;
private Ip4Address tunnelDst = null;
+ private Byte qfi = null;
+ private boolean qfiPush = false;
+ private boolean qfiMatch = false;
public Builder() {
@@ -342,8 +379,36 @@
return this;
}
- public Builder withSchedulingPriority(int schedulingPriority) {
- this.schedulingPriority = schedulingPriority;
+ /**
+ * Set the QoS Flow Identifier for this PDR.
+ *
+ * @param qfi GTP Tunnel QFI
+ * @return This builder object
+ */
+ public Builder withQfi(byte qfi) {
+ this.qfi = qfi;
+ return this;
+ }
+
+ /**
+ * The QoS Flow Identifier should be pushed to the packet.
+ * This is valid for downstream packets and for 5G traffic only.
+ *
+ * @return This builder object
+ */
+ public Builder withQfiPush() {
+ this.qfiPush = true;
+ return this;
+ }
+
+ /**
+ * The QoS Flow Identifier should be matched to the packet.
+ * This is valid for upstream packets and for 5G traffic only.
+ *
+ * @return This builder object
+ */
+ public Builder withQfiMatch() {
+ this.qfiMatch = true;
return this;
}
@@ -393,6 +458,21 @@
return this;
}
+ /**
+ * Set the tunnel ID, destination IP and QFI of the GTP tunnel that this PDR matches on.
+ *
+ * @param teid GTP tunnel ID
+ * @param tunnelDst GTP tunnel destination IP
+ * @param qfi GTP QoS Flow Identifier
+ * @return This builder object
+ */
+ public Builder withTunnel(ImmutableByteSequence teid, Ip4Address tunnelDst, byte qfi) {
+ this.teid = teid;
+ this.tunnelDst = tunnelDst;
+ this.qfi = qfi;
+ return this;
+ }
+
public PacketDetectionRule build() {
// Some match keys are required.
checkArgument(
@@ -401,9 +481,15 @@
"Either a UE address or a TEID and Tunnel destination must be provided, but not both.");
// Action parameters are optional but must be all provided together if they are provided
checkArgument(
- (sessionId != null && ctrId != null && localFarId != null && schedulingPriority != null) ||
- (sessionId == null && ctrId == null && localFarId == null && schedulingPriority == null),
+ (sessionId != null && ctrId != null && localFarId != null) ||
+ (sessionId == null && ctrId == null && localFarId == null),
"PDR action parameters must be provided together or not at all.");
+ checkArgument(!qfiPush || !qfiMatch,
+ "Either match of push QFI can be true, not both.");
+ checkArgument(!qfiPush || qfi != null,
+ "A QFI must be provided when pushing QFI to the packet.");
+ checkArgument(!qfiMatch || qfi != null,
+ "A QFI must be provided when matching QFI on the packet.");
Type type;
if (teid != null) {
if (sessionId != null) {
@@ -418,8 +504,9 @@
type = Type.MATCH_UNENCAPPED_NO_ACTION;
}
}
- return new PacketDetectionRule(sessionId, ctrId, localFarId, schedulingPriority,
- ueAddr, teid, tunnelDst, type);
+ return new PacketDetectionRule(sessionId, ctrId, localFarId, ueAddr,
+ qfi, teid, tunnelDst, type,
+ qfiPush, qfiMatch);
}
}
}