Refactor of UpfProgrammable APIs
Change-Id: I792659ad4a163d7115d7320bb33c11534edd484a
Signed-off-by: Daniele Moro <daniele@opennetworking.org>
(cherry picked from commit a57652d92bdd01b1e77bffbac78a44f96fb385f3)
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
deleted file mode 100644
index bfed1ce..0000000
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/ForwardingActionRule.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright 2021-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 org.onlab.packet.Ip4Address;
-import org.onlab.util.ImmutableByteSequence;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * A single Forwarding Action Rule (FAR), an entity described in the 3GPP
- * specifications (although that does not mean that this class is 3GPP
- * compliant). An instance of this class will be generated by a logical switch
- * write request to the database-style FAR P4 table, and the resulting instance
- * should contain all the information needed to reproduce that logical switch
- * FAR in the event of a client read request. The instance should also contain
- * sufficient information (or expose the means to retrieve such information) to
- * generate the corresponding dataplane forwarding state that implements the FAR.
- */
-public final class ForwardingActionRule {
- // Match Keys
- private final ImmutableByteSequence sessionId; // The PFCP session identifier that created this FAR
- private final int farId; // PFCP session-local identifier for this FAR
- // Action parameters
- private final boolean notifyFlag; // Should this FAR notify the control plane when it sees a packet?
- private final boolean dropFlag;
- private final boolean bufferFlag;
- private final GtpTunnel tunnel; // The GTP tunnel that this FAR should encapsulate packets with (if downlink)
-
- private static final int SESSION_ID_BITWIDTH = 96;
-
- private ForwardingActionRule(ImmutableByteSequence sessionId, Integer farId,
- boolean notifyFlag, GtpTunnel tunnel, boolean dropFlag, boolean bufferFlag) {
- this.sessionId = sessionId;
- this.farId = farId;
- this.notifyFlag = notifyFlag;
- this.tunnel = tunnel;
- this.dropFlag = dropFlag;
- this.bufferFlag = bufferFlag;
- }
-
- /**
- * Return a new instance of this FAR with the action parameters stripped, leaving only the match keys.
- *
- * @return a new FAR with only match keys
- */
- public ForwardingActionRule withoutActionParams() {
- return ForwardingActionRule.builder()
- .setFarId(farId)
- .withSessionId(sessionId)
- .build();
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Return a string representing the dataplane action applied by this FAR.
- *
- * @return a string representing the FAR action
- */
- public String actionString() {
- String actionName;
- String actionParams = "";
- if (dropFlag) {
- actionName = "Drop";
- } else if (bufferFlag) {
- actionName = "Buffer";
- } 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());
- } else {
- actionName = "Forward";
- }
- if (notifyFlag) {
- actionName += "+NotifyCP";
- }
-
- return String.format("%s(%s)", actionName, actionParams);
- }
-
- @Override
- public String toString() {
- String matchKeys = String.format("ID=%d, SEID=%s", farId, sessionId.toString());
- String actionString = actionString();
-
- return String.format("FAR{Match(%s) -> %s}", matchKeys, actionString);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- ForwardingActionRule that = (ForwardingActionRule) obj;
-
- // Safe comparisons between potentially null objects
- return (this.dropFlag == that.dropFlag &&
- this.bufferFlag == that.bufferFlag &&
- this.notifyFlag == that.notifyFlag &&
- this.farId == that.farId &&
- Objects.equals(this.tunnel, that.tunnel) &&
- Objects.equals(this.sessionId, that.sessionId));
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(sessionId, farId, notifyFlag, tunnel, dropFlag, bufferFlag);
- }
-
- /**
- * Get the ID of the PFCP Session that produced this FAR.
- *
- * @return PFCP session ID
- */
- public ImmutableByteSequence sessionId() {
- return sessionId;
- }
-
- /**
- * Get the PFCP session-local ID of the FAR that should apply to packets that match this PDR.
- *
- * @return PFCP session-local FAR ID
- */
- public int farId() {
- return farId;
- }
-
- /**
- * True if this FAR does not drop packets.
- *
- * @return true if FAR is forwards
- */
- public boolean forwards() {
- return !dropFlag;
- }
-
- /**
- * True if this FAR encapsulates packets in a GTP tunnel, and false otherwise.
- *
- * @return true is FAR encapsulates
- */
- public boolean encaps() {
- return tunnel != null;
- }
-
- /**
- * Returns true if this FAR drops packets, and false otherwise.
- *
- * @return true if this FAR drops
- */
- public boolean drops() {
- return dropFlag;
- }
-
- /**
- * Returns true if this FAR notifies the control plane on receiving a packet, and false otherwise.
- *
- * @return true if this FAR notifies the cp
- */
- public boolean notifies() {
- return notifyFlag;
- }
-
-
- /**
- * Returns true if this FAR buffers incoming packets, and false otherwise.
- *
- * @return true if this FAR buffers
- */
- public boolean buffers() {
- return bufferFlag;
- }
-
- /**
- * A description of the tunnel that this FAR will encapsulate packets with, if it is a downlink FAR. If the FAR
- * is uplink, there will be no such tunnel and this method wil return null.
- *
- * @return A GtpTunnel instance containing a tunnel sourceIP, destIP, and GTPU TEID, or null if the FAR is uplink.
- */
- public GtpTunnel tunnel() {
- return tunnel;
- }
-
- /**
- * Get the source UDP port of the GTP tunnel that this FAR will encapsulate packets with.
- *
- * @return GTP tunnel source UDP port
- */
- public Short tunnelSrcPort() {
- return tunnel != null ? tunnel.srcPort() : null;
- }
-
- /**
- * Get the source IP of the GTP tunnel that this FAR will encapsulate packets with.
- *
- * @return GTP tunnel source IP
- */
- public Ip4Address tunnelSrc() {
- if (tunnel == null) {
- return null;
- }
- return tunnel.src();
- }
-
- /**
- * Get the destination IP of the GTP tunnel that this FAR will encapsulate packets with.
- *
- * @return GTP tunnel destination IP
- */
- public Ip4Address tunnelDst() {
- if (tunnel == null) {
- return null;
- }
- return tunnel.dst();
- }
-
- /**
- * Get the identifier of the GTP tunnel that this FAR will encapsulate packets with.
- *
- * @return GTP tunnel ID
- */
- public ImmutableByteSequence teid() {
- if (tunnel == null) {
- return null;
- }
- return tunnel.teid();
- }
-
- public static class Builder {
- private ImmutableByteSequence sessionId = null;
- private Integer farId = null;
- private GtpTunnel tunnel = null;
- private boolean dropFlag = false;
- private boolean bufferFlag = false;
- private boolean notifyCp = false;
-
- public Builder() {
- }
-
- /**
- * Set the ID of the PFCP session that created this FAR.
- *
- * @param sessionId PFC session ID
- * @return This builder object
- */
- public Builder withSessionId(ImmutableByteSequence sessionId) {
- this.sessionId = sessionId;
- return this;
- }
-
- /**
- * Set the ID of the PFCP session that created this FAR.
- *
- * @param sessionId PFC session ID
- * @return This builder object
- */
- public Builder withSessionId(long sessionId) {
- try {
- this.sessionId = ImmutableByteSequence.copyFrom(sessionId).fit(SESSION_ID_BITWIDTH);
- } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
- // This error is literally impossible
- }
- return this;
- }
-
- /**
- * Set the PFCP Session-local ID of this FAR.
- *
- * @param farId PFCP session-local FAR ID
- * @return This builder object
- */
- public Builder setFarId(int farId) {
- this.farId = farId;
- return this;
- }
-
- /**
- * Make this FAR forward incoming packets.
- *
- * @param flag the flag value to set
- * @return This builder object
- */
- public Builder setForwardFlag(boolean flag) {
- this.dropFlag = !flag;
- return this;
- }
-
- /**
- * Make this FAR drop incoming packets.
- *
- * @param flag the flag value to set
- * @return This builder object
- */
- public Builder setDropFlag(boolean flag) {
- this.dropFlag = flag;
- return this;
- }
-
- /**
- * Make this FAR buffer incoming packets.
- *
- * @param flag the flag value to set
- * @return This builder object
- */
- public Builder setBufferFlag(boolean flag) {
- this.bufferFlag = flag;
- return this;
- }
-
- /**
- * Set a flag specifying if the control plane should be notified when this FAR is hit.
- *
- * @param notifyCp true if FAR notifies control plane
- * @return This builder object
- */
- public Builder setNotifyFlag(boolean notifyCp) {
- this.notifyCp = notifyCp;
- return this;
- }
-
- /**
- * Set the GTP tunnel that this FAR should encapsulate packets with.
- *
- * @param tunnel GTP tunnel
- * @return This builder object
- */
- public Builder setTunnel(GtpTunnel tunnel) {
- this.tunnel = tunnel;
- return this;
- }
-
- /**
- * Set the unidirectional GTP tunnel that this FAR should encapsulate packets with.
- *
- * @param src GTP tunnel source IP
- * @param dst GTP tunnel destination IP
- * @param teid GTP tunnel ID
- * @return This builder object
- */
- public Builder setTunnel(Ip4Address src, Ip4Address dst, ImmutableByteSequence teid) {
- return this.setTunnel(GtpTunnel.builder()
- .setSrc(src)
- .setDst(dst)
- .setTeid(teid)
- .build());
- }
-
- /**
- * Set the unidirectional GTP tunnel that this FAR should encapsulate packets with.
- *
- * @param src GTP tunnel source IP
- * @param dst GTP tunnel destination IP
- * @param teid GTP tunnel ID
- * @param srcPort GTP tunnel UDP source port (destination port is hardcoded as 2152)
- * @return This builder object
- */
- public Builder setTunnel(Ip4Address src, Ip4Address dst, ImmutableByteSequence teid, short srcPort) {
- return this.setTunnel(GtpTunnel.builder()
- .setSrc(src)
- .setDst(dst)
- .setTeid(teid)
- .setSrcPort(srcPort)
- .build());
- }
-
- public ForwardingActionRule build() {
- // All match keys are required
- checkNotNull(sessionId, "Session ID is required");
- checkNotNull(farId, "FAR ID is required");
- return new ForwardingActionRule(sessionId, farId, notifyCp, tunnel, dropFlag, bufferFlag);
- }
- }
-}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/GtpTunnel.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/GtpTunnel.java
deleted file mode 100644
index bc262c7..0000000
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/GtpTunnel.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2021-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 org.onlab.packet.Ip4Address;
-import org.onlab.util.ImmutableByteSequence;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * A structure representing a unidirectional GTP tunnel.
- */
-public final class GtpTunnel {
- private final Ip4Address src; // The source address of the unidirectional tunnel
- private final Ip4Address dst; // The destination address of the unidirectional tunnel
- private final ImmutableByteSequence teid; // Tunnel Endpoint Identifier
- private final short srcPort; // Tunnel destination port, default 2152
-
- private GtpTunnel(Ip4Address src, Ip4Address dst, ImmutableByteSequence teid,
- Short srcPort) {
- this.src = src;
- this.dst = dst;
- this.teid = teid;
- this.srcPort = srcPort;
- }
-
- public static GtpTunnelBuilder builder() {
- return new GtpTunnelBuilder();
- }
-
- @Override
- public String toString() {
- return String.format("GTP-Tunnel(%s -> %s, TEID:%s)",
- src.toString(), dst.toString(), teid.toString());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- GtpTunnel that = (GtpTunnel) obj;
-
- return (this.src.equals(that.src) &&
- this.dst.equals(that.dst) &&
- this.teid.equals(that.teid) &&
- (this.srcPort == that.srcPort));
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(src, dst, teid, srcPort);
- }
-
- /**
- * Get the source IP address of this unidirectional GTP tunnel.
- *
- * @return tunnel source IP
- */
- public Ip4Address src() {
- return this.src;
- }
-
- /**
- * Get the destination address of this unidirectional GTP tunnel.
- *
- * @return tunnel destination IP
- */
- public Ip4Address dst() {
- return this.dst;
- }
-
- /**
- * Get the ID of this unidirectional GTP tunnel.
- *
- * @return tunnel ID
- */
- public ImmutableByteSequence teid() {
- return this.teid;
- }
-
-
- /**
- * Get the source L4 port of this unidirectional GTP tunnel.
- *
- * @return tunnel source port
- */
- public Short srcPort() {
- return this.srcPort;
- }
-
- public static class GtpTunnelBuilder {
- private Ip4Address src;
- private Ip4Address dst;
- private ImmutableByteSequence teid;
- private short srcPort = 2152; // Default value is equal to GTP tunnel dst port
-
- public GtpTunnelBuilder() {
- this.src = null;
- this.dst = null;
- this.teid = null;
- }
-
- /**
- * Set the source IP address of the unidirectional GTP tunnel.
- *
- * @param src GTP tunnel source IP
- * @return This builder object
- */
- public GtpTunnelBuilder setSrc(Ip4Address src) {
- this.src = src;
- return this;
- }
-
- /**
- * Set the destination IP address of the unidirectional GTP tunnel.
- *
- * @param dst GTP tunnel destination IP
- * @return This builder object
- */
- public GtpTunnelBuilder setDst(Ip4Address dst) {
- this.dst = dst;
- return this;
- }
-
- /**
- * Set the identifier of this unidirectional GTP tunnel.
- *
- * @param teid tunnel ID
- * @return This builder object
- */
- public GtpTunnelBuilder setTeid(ImmutableByteSequence teid) {
- this.teid = teid;
- return this;
- }
-
- /**
- * Set the identifier of this unidirectional GTP tunnel.
- *
- * @param teid tunnel ID
- * @return This builder object
- */
- public GtpTunnelBuilder setTeid(long teid) {
- this.teid = ImmutableByteSequence.copyFrom(teid);
- return this;
- }
-
- /**
- * Set the source port of this unidirectional GTP tunnel.
- *
- * @param srcPort tunnel source port
- * @return this builder object
- */
- public GtpTunnelBuilder setSrcPort(short srcPort) {
- this.srcPort = srcPort;
- return this;
- }
-
- public GtpTunnel build() {
- checkNotNull(src, "Tunnel source address cannot be null");
- checkNotNull(dst, "Tunnel destination address cannot be null");
- checkNotNull(teid, "Tunnel TEID cannot be null");
- return new GtpTunnel(this.src, this.dst, this.teid, srcPort);
- }
- }
-}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/GtpTunnelPeer.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/GtpTunnelPeer.java
new file mode 100644
index 0000000..a3cf662
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/GtpTunnelPeer.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2021-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.annotations.Beta;
+import org.onlab.packet.Ip4Address;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * A structure representing a GTP tunnel peer.
+ * The GTP Tunnel Peer is used by UPF to identify a second end of a GTP tunnel.
+ * The source and destination tunnel IPv4 addresses, and source UDP port are set
+ * based on the information from this structure.
+ */
+@Beta
+public final class GtpTunnelPeer implements UpfEntity {
+ // Match keys
+ private final byte tunPeerId;
+ // Action parameters
+ private final Ip4Address src; // The source address of the unidirectional tunnel
+ private final Ip4Address dst; // The destination address of the unidirectional tunnel
+ private final short srcPort; // Tunnel source port, default 2152
+
+ private GtpTunnelPeer(byte tunPeerId, Ip4Address src, Ip4Address dst, short srcPort) {
+ this.tunPeerId = tunPeerId;
+ this.src = src;
+ this.dst = dst;
+ this.srcPort = srcPort;
+ }
+
+ public static GtpTunnelPeer.Builder builder() {
+ return new GtpTunnelPeer.Builder();
+ }
+
+ @Override
+ public String toString() {
+ return String.format("GTP-Tunnel-Peer(%s -> src:%s, dst:%s srcPort:%s)",
+ tunPeerId, src.toString(), dst.toString(), srcPort);
+ }
+
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+
+ if (object == null) {
+ return false;
+ }
+
+ if (getClass() != object.getClass()) {
+ return false;
+ }
+
+ GtpTunnelPeer that = (GtpTunnelPeer) object;
+ return (this.tunPeerId == that.tunPeerId &&
+ this.src.equals(that.src) &&
+ this.dst.equals(that.dst) &&
+ (this.srcPort == that.srcPort));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(src, dst, srcPort);
+ }
+
+ /**
+ * Get the ID of the GTP tunnel peer.
+ *
+ * @return GTP tunnel peer ID
+ */
+ public byte tunPeerId() {
+ return tunPeerId;
+ }
+
+ /**
+ * Get the source IP address of this unidirectional GTP tunnel.
+ *
+ * @return tunnel source IP
+ */
+ public Ip4Address src() {
+ return this.src;
+ }
+
+ /**
+ * Get the destination address of this unidirectional GTP tunnel.
+ *
+ * @return tunnel destination IP
+ */
+ public Ip4Address dst() {
+ return this.dst;
+ }
+
+ /**
+ * Get the source L4 port of this unidirectional GTP tunnel.
+ *
+ * @return tunnel source port
+ */
+ public short srcPort() {
+ return this.srcPort;
+ }
+
+ @Override
+ public UpfEntityType type() {
+ return UpfEntityType.TUNNEL_PEER;
+ }
+
+ public static class Builder {
+ private Byte tunPeerId = null;
+ private Ip4Address src = null;
+ private Ip4Address dst = null;
+ private short srcPort = 2152; // Default value is equal to GTP tunnel dst port
+
+ public Builder() {
+
+ }
+
+ /**
+ * Set the ID of the GTP Tunnel peer.
+ *
+ * @param tunPeerId GTP tunnel peer ID
+ * @return This builder object
+ */
+ public GtpTunnelPeer.Builder withTunnelPeerId(byte tunPeerId) {
+ this.tunPeerId = tunPeerId;
+ return this;
+ }
+
+ /**
+ * Set the source IP address of the unidirectional GTP tunnel.
+ *
+ * @param src GTP tunnel source IP
+ * @return This builder object
+ */
+ public GtpTunnelPeer.Builder withSrcAddr(Ip4Address src) {
+ this.src = src;
+ return this;
+ }
+
+ /**
+ * Set the destination IP address of the unidirectional GTP tunnel.
+ *
+ * @param dst GTP tunnel destination IP
+ * @return This builder object
+ */
+ public GtpTunnelPeer.Builder withDstAddr(Ip4Address dst) {
+ this.dst = dst;
+ return this;
+ }
+
+ /**
+ * Set the source port of this unidirectional GTP tunnel.
+ *
+ * @param srcPort tunnel source port
+ * @return this builder object
+ */
+ public GtpTunnelPeer.Builder withSrcPort(short srcPort) {
+ this.srcPort = srcPort;
+ return this;
+ }
+
+ public GtpTunnelPeer build() {
+ checkArgument(tunPeerId != null, "Tunnel Peer ID must be provided");
+ checkArgument(src != null, "Tunnel source address cannot be null");
+ checkArgument(dst != null, "Tunnel destination address cannot be null");
+ return new GtpTunnelPeer(this.tunPeerId, this.src, this.dst, srcPort);
+ }
+
+ }
+
+}
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
deleted file mode 100644
index f607d87..0000000
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/PacketDetectionRule.java
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright 2021-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 org.onlab.packet.Ip4Address;
-import org.onlab.util.ImmutableByteSequence;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-/**
- * A single Packet Detection Rule (PDR), an entity described in the 3GPP
- * specifications (although that does not mean that this class is 3GPP
- * compliant). An instance of this class will be generated by a logical switch
- * write request to the database-style PDR P4 table, and the resulting instance
- * should contain all the information needed to reproduce that logical switch
- * PDR in the event of a client read request. The instance should also contain
- * sufficient information (or expose the means to retrieve such information) to
- * generate the corresponding dataplane forwarding state that implements the PDR.
- */
-public final class PacketDetectionRule {
- // Match keys
- private final Ip4Address ueAddr; // The UE IP address that this PDR matches on
- private final ImmutableByteSequence teid; // The Tunnel Endpoint ID that this PDR matches on
- private final Ip4Address tunnelDst; // The tunnel destination address that this PDR matches on
- // Action parameters
- private final ImmutableByteSequence sessionId; // The ID of the PFCP session that created this PDR
- 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 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, 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.qfi = qfi;
- this.type = type;
- this.qfiPush = qfiPush;
- this.qfiMatch = qfiMatch;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Return a string representing the match conditions of this PDR.
- *
- * @return a string representing the PDR match conditions
- */
- public String matchString() {
- if (matchesEncapped()) {
- 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());
- }
- }
-
- @Override
- public String toString() {
- String actionParams = "";
- if (hasActionParameters()) {
- 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)}",
- matchString(), actionParams);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- PacketDetectionRule that = (PacketDetectionRule) obj;
-
- // Safe comparisons between potentially null objects
- return (this.type.equals(that.type) &&
- Objects.equals(this.teid, that.teid) &&
- Objects.equals(this.tunnelDst, that.tunnelDst) &&
- Objects.equals(this.ueAddr, that.ueAddr) &&
- Objects.equals(this.ctrId, that.ctrId) &&
- Objects.equals(this.sessionId, that.sessionId) &&
- Objects.equals(this.farId, that.farId) &&
- 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,
- qfi, type);
- }
-
- /**
- * Instances created as a result of DELETE write requests will not have
- * action parameters, only match keys. This method should be used to avoid
- * null pointer exceptions in those instances.
- *
- * @return true if this instance has PDR action parameters, false otherwise.
- */
- public boolean hasActionParameters() {
- return type == Type.MATCH_ENCAPPED || type == Type.MATCH_UNENCAPPED;
- }
-
- /**
- * Return a new instance of this PDR with the action parameters stripped,
- * leaving only the match keys.
- *
- * @return a new PDR with only match keys
- */
- public PacketDetectionRule withoutActionParams() {
- if (matchesEncapped()) {
- PacketDetectionRule.Builder pdrBuilder = PacketDetectionRule.builder()
- .withTeid(teid)
- .withTunnelDst(tunnelDst);
- if (this.hasQfi() && this.matchQfi()) {
- pdrBuilder.withQfiMatch();
- pdrBuilder.withQfi(qfi);
- }
- return pdrBuilder.build();
- } else {
- return PacketDetectionRule.builder()
- .withUeAddr(ueAddr).build();
- }
- }
-
- /**
- * True if this PDR matches on packets received with a GTP header, and false
- * otherwise.
- *
- * @return true if the PDR matches only encapsulated packets
- */
- public boolean matchesEncapped() {
- return type == Type.MATCH_ENCAPPED ||
- type == Type.MATCH_ENCAPPED_NO_ACTION;
- }
-
- /**
- * True if this PDR matches on packets received without a GTP header, and
- * false otherwise.
- *
- * @return true if the PDR matches only un-encapsulated packets
- */
- public boolean matchesUnencapped() {
- return type == Type.MATCH_UNENCAPPED ||
- type == Type.MATCH_UNENCAPPED_NO_ACTION;
- }
-
- /**
- * Get the ID of the PFCP session that produced this PDR.
- *
- * @return PFCP session ID
- */
- public ImmutableByteSequence sessionId() {
- return sessionId;
- }
-
- /**
- * Get the UE IP address that this PDR matches on.
- *
- * @return UE IP address
- */
- public Ip4Address ueAddress() {
- return ueAddr;
- }
-
- /**
- * Get the identifier of the GTP tunnel that this PDR matches on.
- *
- * @return GTP tunnel ID
- */
- public ImmutableByteSequence teid() {
- return teid;
- }
-
- /**
- * Get the destination IP of the GTP tunnel that this PDR matches on.
- *
- * @return GTP tunnel destination IP
- */
- public Ip4Address tunnelDest() {
- return tunnelDst;
- }
-
- /**
- * Get the dataplane PDR counter cell ID that this PDR is assigned.
- *
- * @return PDR counter cell ID
- */
- public int counterId() {
- return ctrId;
- }
-
- /**
- * Get the PFCP session-local ID of the far that should apply to packets
- * that this PDR matches.
- *
- * @return PFCP session-local FAR ID
- */
- public int farId() {
- return farId;
- }
-
- /**
- * Get the QoS Flow Identifier for this PDR.
- *
- * @return QoS Flow Identifier
- */
- public byte qfi() {
- return qfi;
- }
-
- /**
- * Returns whether QFi should be pushed to the packet.
- *
- * @return True if the QFI should be pushed to the packet, false otherwise
- */
- 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 {
- /**
- * Match on packets that are encapsulated in a GTP tunnel.
- */
- MATCH_ENCAPPED,
- /**
- * Match on packets that are not encapsulated in a GTP tunnel.
- */
- MATCH_UNENCAPPED,
- /**
- * For PDRs that match on encapsulated packets but do not yet have any
- * action parameters set.
- * These are usually built in the context of P4Runtime DELETE write requests.
- */
- MATCH_ENCAPPED_NO_ACTION,
- /**
- * For PDRs that match on unencapsulated packets but do not yet have any
- * action parameters set.
- * These are usually built in the context of P4Runtime DELETE write requests.
- */
- MATCH_UNENCAPPED_NO_ACTION
- }
-
- public static class Builder {
- private ImmutableByteSequence sessionId = null;
- private Integer ctrId = null;
- private Integer localFarId = null;
- private Integer schedulingPriority = null;
- 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() {
-
- }
-
- /**
- * Set the ID of the PFCP session that produced this PDR.
- *
- * @param sessionId PFCP session ID
- * @return This builder object
- */
- public Builder withSessionId(ImmutableByteSequence sessionId) {
- this.sessionId = sessionId;
- return this;
- }
-
- /**
- * Set the ID of the PFCP session that produced this PDR.
- *
- * @param sessionId PFCP session ID
- * @return This builder object
- */
- public Builder withSessionId(long sessionId) {
- try {
- this.sessionId = ImmutableByteSequence.copyFrom(sessionId)
- .fit(SESSION_ID_BITWIDTH);
- } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
- // This error is literally impossible
- }
- return this;
- }
-
- /**
- * Set the UE IP address that this PDR matches on.
- *
- * @param ueAddr UE IP address
- * @return This builder object
- */
- public Builder withUeAddr(Ip4Address ueAddr) {
- this.ueAddr = ueAddr;
- return this;
- }
-
- /**
- * Set the dataplane PDR counter cell ID that this PDR is assigned.
- *
- * @param ctrId PDR counter cell ID
- * @return This builder object
- */
- public Builder withCounterId(int ctrId) {
- this.ctrId = ctrId;
- return this;
- }
-
-
- /**
- * Set the PFCP session-local ID of the far that should apply to packets that this PDR matches.
- *
- * @param localFarId PFCP session-local FAR ID
- * @return This builder object
- */
- public Builder withLocalFarId(int localFarId) {
- this.localFarId = localFarId;
- return this;
- }
-
- /**
- * 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;
- }
-
- /**
- * Set the identifier of the GTP tunnel that this PDR matches on.
- *
- * @param teid GTP tunnel ID
- * @return This builder object
- */
- public Builder withTeid(int teid) {
- this.teid = ImmutableByteSequence.copyFrom(teid);
- return this;
- }
-
- /**
- * Set the identifier of the GTP tunnel that this PDR matches on.
- *
- * @param teid GTP tunnel ID
- * @return This builder object
- */
- public Builder withTeid(ImmutableByteSequence teid) {
- this.teid = teid;
- return this;
- }
-
- /**
- * Set the destination IP of the GTP tunnel that this PDR matches on.
- *
- * @param tunnelDst GTP tunnel destination IP
- * @return This builder object
- */
- public Builder withTunnelDst(Ip4Address tunnelDst) {
- this.tunnelDst = tunnelDst;
- return this;
- }
-
- /**
- * Set the tunnel ID and destination IP of the GTP tunnel that this PDR matches on.
- *
- * @param teid GTP tunnel ID
- * @param tunnelDst GTP tunnel destination IP
- * @return This builder object
- */
- public Builder withTunnel(ImmutableByteSequence teid, Ip4Address tunnelDst) {
- this.teid = teid;
- this.tunnelDst = tunnelDst;
- 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(
- (ueAddr != null && teid == null && tunnelDst == null) ||
- (ueAddr == null && teid != null && tunnelDst != null),
- "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) ||
- (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) {
- type = Type.MATCH_ENCAPPED;
- } else {
- type = Type.MATCH_ENCAPPED_NO_ACTION;
- }
- } else {
- if (sessionId != null) {
- type = Type.MATCH_UNENCAPPED;
- } else {
- type = Type.MATCH_UNENCAPPED_NO_ACTION;
- }
- }
- return new PacketDetectionRule(sessionId, ctrId, localFarId, ueAddr,
- qfi, teid, tunnelDst, type,
- qfiPush, qfiMatch);
- }
- }
-}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/SessionDownlink.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/SessionDownlink.java
new file mode 100644
index 0000000..c35410b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/SessionDownlink.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2021-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.annotations.Beta;
+import org.onlab.packet.Ip4Address;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A structure representing the UE Session on the UPF-programmable device.
+ * Provides means to set up the UE Session in the downlink direction.
+ */
+@Beta
+public final class SessionDownlink implements UpfEntity {
+ // Match Keys
+ private final Ip4Address ueAddress;
+ // Action parameters
+ private final Byte tunPeerId;
+ private final boolean buffering;
+ private final boolean dropping;
+
+ private SessionDownlink(Ip4Address ipv4Address,
+ Byte tunPeerId,
+ boolean buffering,
+ boolean drop) {
+ this.ueAddress = ipv4Address;
+ this.tunPeerId = tunPeerId;
+ this.buffering = buffering;
+ this.dropping = drop;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object == null) {
+ return false;
+ }
+ if (getClass() != object.getClass()) {
+ return false;
+ }
+
+ SessionDownlink that = (SessionDownlink) object;
+
+ return this.buffering == that.buffering &&
+ this.dropping == that.dropping &&
+ Objects.equals(ueAddress, that.ueAddress) &&
+ Objects.equals(tunPeerId, that.tunPeerId);
+ }
+
+ public int hashCode() {
+ return java.util.Objects.hash(ueAddress, tunPeerId, buffering, dropping);
+ }
+
+ @Override
+ public String toString() {
+ return "UESessionDL{" + matchString() + " -> " + actionString();
+ }
+
+ private String matchString() {
+ return "Match(ue_addr=" + this.ueAddress() + ")";
+ }
+
+ private String actionString() {
+ StringBuilder actionStrBuilder = new StringBuilder("(");
+ if (this.needsBuffering() && this.needsDropping()) {
+ actionStrBuilder.append("BUFF+DROP, ");
+ } else if (this.needsBuffering()) {
+ actionStrBuilder.append("BUFF, ");
+ } else if (this.needsDropping()) {
+ actionStrBuilder.append("DROP, ");
+ } else {
+ actionStrBuilder.append("FWD, ");
+ }
+ return actionStrBuilder.append(" tun_peer=").append(this.tunPeerId()).append(")")
+ .toString();
+ }
+
+ /**
+ * True if this UE Session needs buffering of the downlink traffic.
+ *
+ * @return true if the UE Session needs buffering.
+ */
+ public boolean needsBuffering() {
+ return buffering;
+ }
+
+ /**
+ * True if this UE Session needs dropping of the downlink traffic.
+ *
+ * @return true if the UE Session needs dropping.
+ */
+ public boolean needsDropping() {
+ return dropping;
+ }
+
+ /**
+ * Get the UE IP address of this downlink UE session.
+ *
+ * @return UE IP address
+ */
+ public Ip4Address ueAddress() {
+ return ueAddress;
+ }
+
+ /**
+ * Get the GTP tunnel peer ID that is set by this UE Session rule.
+ *
+ * @return GTP tunnel peer ID
+ */
+ public Byte tunPeerId() {
+ return tunPeerId;
+ }
+
+ @Override
+ public UpfEntityType type() {
+ return UpfEntityType.SESSION_DOWNLINK;
+ }
+
+ public static class Builder {
+ private Ip4Address ueAddress = null;
+ private Byte tunPeerId = null;
+ private boolean buffer = false;
+ private boolean drop = false;
+
+ public Builder() {
+
+ }
+
+ /**
+ * Set the UE IP address that this downlink UE session rule matches on.
+ *
+ * @param ueAddress UE IP address
+ * @return This builder object
+ */
+ public Builder withUeAddress(Ip4Address ueAddress) {
+ this.ueAddress = ueAddress;
+ return this;
+ }
+
+ /**
+ * Set the GTP tunnel peer ID that is set by this UE Session rule.
+ *
+ * @param tunnelPeerId GTP tunnel peer ID
+ * @return This builder object
+ */
+ public Builder withGtpTunnelPeerId(Byte tunnelPeerId) {
+ this.tunPeerId = tunnelPeerId;
+ return this;
+ }
+
+ /**
+ * Sets whether to buffer downlink UE session traffic or not.
+ *
+ * @param buffer True if request to buffer, false otherwise
+ * @return This builder object
+ */
+ public Builder needsBuffering(boolean buffer) {
+ this.buffer = buffer;
+ return this;
+ }
+
+ /**
+ * Sets whether to drop downlink UE session traffic or not.
+ *
+ * @param drop True if request to buffer, false otherwise
+ * @return This builder object
+ */
+ public Builder needsDropping(boolean drop) {
+ this.drop = drop;
+ return this;
+ }
+
+ public SessionDownlink build() {
+ // Match fields are required
+ checkNotNull(ueAddress, "UE address must be provided");
+ return new SessionDownlink(ueAddress, tunPeerId, buffer, drop);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/SessionUplink.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/SessionUplink.java
new file mode 100644
index 0000000..70db84c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/SessionUplink.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2021-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.annotations.Beta;
+import org.onlab.packet.Ip4Address;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A structure representing the UE Session on the UPF-programmable device.
+ * Provides means to set up the UE Session in the uplink direction.
+ */
+@Beta
+public final class SessionUplink implements UpfEntity {
+ // Match Keys
+ private final Ip4Address tunDestAddr; // The tunnel destination address (N3/S1U IPv4 address)
+ private final Integer teid; // The Tunnel Endpoint ID that this UeSession matches on
+
+ // Action parameters
+ private final boolean dropping; // Used to convey dropping information
+
+ private SessionUplink(Ip4Address tunDestAddr,
+ Integer teid,
+ boolean drop) {
+ this.tunDestAddr = tunDestAddr;
+ this.teid = teid;
+ this.dropping = drop;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object == null) {
+ return false;
+ }
+ if (getClass() != object.getClass()) {
+ return false;
+ }
+
+ SessionUplink that = (SessionUplink) object;
+
+ return this.dropping == that.dropping &&
+ Objects.equals(tunDestAddr, that.tunDestAddr) &&
+ Objects.equals(teid, that.teid);
+ }
+
+ public int hashCode() {
+ return Objects.hash(tunDestAddr, teid, dropping);
+ }
+
+ @Override
+ public String toString() {
+ return "UESessionUL{" + matchString() + " -> " + actionString();
+ }
+
+ private String matchString() {
+ return "Match(tun_dst_addr=" + this.tunDstAddr() + ", TEID=" + this.teid() + ")";
+ }
+
+ private String actionString() {
+ StringBuilder actionStrBuilder = new StringBuilder("(");
+ if (this.needsDropping()) {
+ actionStrBuilder.append("DROP");
+
+ } else {
+ actionStrBuilder.append("FWD");
+ }
+ return actionStrBuilder.append(")").toString();
+ }
+
+ /**
+ * True if this UE Session needs dropping of the uplink traffic.
+ *
+ * @return true if the UE Session needs dropping.
+ */
+ public boolean needsDropping() {
+ return dropping;
+ }
+
+ /**
+ * Get the tunnel destination IP address in the uplink UE session (N3/S1U IP address).
+ *
+ * @return UE IP address
+ */
+ public Ip4Address tunDstAddr() {
+ return tunDestAddr;
+ }
+
+ /**
+ * Get the identifier of the GTP tunnel that this UE Session rule matches on.
+ *
+ * @return GTP tunnel ID
+ */
+ public Integer teid() {
+ return teid;
+ }
+
+ @Override
+ public UpfEntityType type() {
+ return UpfEntityType.SESSION_UPLINK;
+ }
+
+ public static class Builder {
+ private Ip4Address tunDstAddr = null;
+ private Integer teid = null;
+ private boolean drop = false;
+
+ public Builder() {
+
+ }
+
+ /**
+ * Set the tunnel destination IP address (N3/S1U address) that this UE Session rule matches on.
+ *
+ * @param tunDstAddr The tunnel destination IP address
+ * @return This builder object
+ */
+ public Builder withTunDstAddr(Ip4Address tunDstAddr) {
+ this.tunDstAddr = tunDstAddr;
+ return this;
+ }
+
+ /**
+ * Set the identifier of the GTP tunnel that this UE Session rule matches on.
+ *
+ * @param teid GTP tunnel ID
+ * @return This builder object
+ */
+ public Builder withTeid(Integer teid) {
+ this.teid = teid;
+ return this;
+ }
+
+
+ /**
+ * Sets whether to drop uplink UE session traffic or not.
+ *
+ * @param drop True if request to buffer, false otherwise
+ * @return This builder object
+ */
+ public Builder needsDropping(boolean drop) {
+ this.drop = drop;
+ return this;
+ }
+
+ public SessionUplink build() {
+ // Match keys are required.
+ checkNotNull(tunDstAddr, "Tunnel destination must be provided");
+ checkNotNull(teid, "TEID must be provided");
+ return new SessionUplink(tunDstAddr, teid, drop);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/PdrStats.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfCounter.java
similarity index 76%
rename from core/api/src/main/java/org/onosproject/net/behaviour/upf/PdrStats.java
rename to core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfCounter.java
index eb4ea18..4eee3fe 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/PdrStats.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfCounter.java
@@ -17,21 +17,26 @@
package org.onosproject.net.behaviour.upf;
+import com.google.common.annotations.Beta;
+
import static com.google.common.base.Preconditions.checkNotNull;
/**
- * A structure for compactly passing PDR counter values for a given counter ID.
- * Contains four counts: Ingress Packets, Ingress Bytes, Egress Packets, Egress Bytes
+ * A structure for compactly passing UPF counter values for a given counter ID.
+ * Contains four counts: Ingress Packets, Ingress Bytes, Egress Packets, Egress Bytes.
+ * UpfCounter can be used ONLY on {@code apply} and {@code readAll} calls in the
+ * {@link UpfDevice} interface.
*/
-public final class PdrStats {
+@Beta
+public final class UpfCounter implements UpfEntity {
private final int cellId;
private final long ingressPkts;
private final long ingressBytes;
private final long egressPkts;
private final long egressBytes;
- private PdrStats(int cellId, long ingressPkts, long ingressBytes,
- long egressPkts, long egressBytes) {
+ private UpfCounter(int cellId, long ingressPkts, long ingressBytes,
+ long egressPkts, long egressBytes) {
this.cellId = cellId;
this.ingressPkts = ingressPkts;
this.ingressBytes = ingressBytes;
@@ -45,12 +50,12 @@
@Override
public String toString() {
- return String.format("PDR-Stats:{ CellID: %d, Ingress:(%dpkts,%dbytes), Egress:(%dpkts,%dbytes) }",
+ return String.format("Stats:{ CellID: %d, Ingress:(%dpkts,%dbytes), Egress:(%dpkts,%dbytes) }",
cellId, ingressPkts, ingressBytes, egressPkts, egressBytes);
}
/**
- * Get the cell ID (index) of the dataplane PDR counter that produced this set of stats.
+ * Get the cell ID (index) of the dataplane counter that produced this set of stats.
*
* @return counter cell ID
*/
@@ -94,6 +99,11 @@
return egressBytes;
}
+ @Override
+ public UpfEntityType type() {
+ return UpfEntityType.COUNTER;
+ }
+
public static class Builder {
private Integer cellId;
private long ingressPkts;
@@ -109,7 +119,7 @@
}
/**
- * Set the Cell ID (index) of the datalane PDR counter that produced this set of stats.
+ * Set the Cell ID (index) of the datalane counter that produced this set of stats.
*
* @param cellId the counter cell ID
* @return This builder
@@ -120,7 +130,7 @@
}
/**
- * Set the number of packets and bytes that hit the PDR counter in the dataplane ingress pipeline.
+ * Set the number of packets and bytes that hit the counter in the dataplane ingress pipeline.
*
* @param ingressPkts ingress packet count
* @param ingressBytes egress packet count
@@ -133,7 +143,7 @@
}
/**
- * Set the number of packets and bytes that hit the PDR counter in the dataplane egress pipeline.
+ * Set the number of packets and bytes that hit the counter in the dataplane egress pipeline.
*
* @param egressPkts egress packet count
* @param egressBytes egress byte count
@@ -145,9 +155,9 @@
return this;
}
- public PdrStats build() {
+ public UpfCounter build() {
checkNotNull(cellId, "CellID must be provided");
- return new PdrStats(cellId, ingressPkts, ingressBytes, egressPkts, egressBytes);
+ return new UpfCounter(cellId, ingressPkts, ingressBytes, egressPkts, egressBytes);
}
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfDevice.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfDevice.java
index e0d9fb4..2b17421 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfDevice.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfDevice.java
@@ -28,157 +28,94 @@
public interface UpfDevice {
/**
- * Remove any state previously created by this API.
+ * Removes any state previously created by this API.
*/
void cleanUp();
/**
- * Remove all interfaces currently installed on the UPF-programmable device.
- */
- void clearInterfaces();
-
- /**
- * Remove all UE flows (PDRs, FARs) currently installed on the UPF-programmable device.
- */
- void clearFlows();
-
- /**
- * Get all ForwardingActionRules currently installed on the UPF-programmable device.
+ * Applies the given UPF entity to the UPF-programmable device.
*
- * @return a collection of installed FARs
- * @throws UpfProgrammableException if FARs are unable to be read
+ * @param entity The UPF entity to be applied.
+ * @throws UpfProgrammableException if the given UPF entity can not be applied or
+ * the operation is not supported on the given UPF entity.
*/
- Collection<ForwardingActionRule> getFars() throws UpfProgrammableException;
+ void apply(UpfEntity entity) throws UpfProgrammableException;
/**
- * Get all PacketDetectionRules currently installed on the UPF-programmable device.
+ * Reads all the UPF entities of the given type from the UPF-programmable device.
*
- * @return a collection of installed PDRs
- * @throws UpfProgrammableException if PDRs are unable to be read
+ * @param entityType The type of entities to read.
+ * @return A collection of installed UPF entities.
+ * @throws UpfProgrammableException if UPF entity type is not available to be read or
+ * the operation is not supported on the given UPF entity type.
*/
- Collection<PacketDetectionRule> getPdrs() throws UpfProgrammableException;
+ Collection<? extends UpfEntity> readAll(UpfEntityType entityType) throws UpfProgrammableException;
/**
- * Get all UPF interface lookup entries currently installed on the UPF-programmable device.
+ * Reads the given UPF counter ID from the UPF-programmable device.
*
- * @return a collection of installed interfaces
- * @throws UpfProgrammableException if interfaces are unable to be read
+ * @param counterId The counter ID from which to read.
+ * @return The content of the UPF counter.
+ * @throws UpfProgrammableException if the counter ID is out of bounds.
*/
- Collection<UpfInterface> getInterfaces() throws UpfProgrammableException;
+ UpfCounter readCounter(int counterId) throws UpfProgrammableException;
/**
- * Add a Packet Detection Rule (PDR) to the given device.
- *
- * @param pdr The PDR to be added
- * @throws UpfProgrammableException if the PDR cannot be installed, or the counter index is out
- * of bounds
- */
- void addPdr(PacketDetectionRule pdr) throws UpfProgrammableException;
-
- /**
- * Remove a previously installed Packet Detection Rule (PDR) from the target device.
- *
- * @param pdr The PDR to be removed
- * @throws UpfProgrammableException if the PDR cannot be found
- */
- void removePdr(PacketDetectionRule pdr) throws UpfProgrammableException;
-
- /**
- * Add a Forwarding Action Rule (FAR) to the given device.
- *
- * @param far The FAR to be added
- * @throws UpfProgrammableException if the FAR cannot be installed
- */
- void addFar(ForwardingActionRule far) throws UpfProgrammableException;
-
- /**
- * Remove a previously installed Forwarding Action Rule (FAR) from the target device.
- *
- * @param far The FAR to be removed
- * @throws UpfProgrammableException if the FAR cannot be found
- */
- void removeFar(ForwardingActionRule far) throws UpfProgrammableException;
-
- /**
- * Install a new interface on the UPF device's interface lookup tables.
- *
- * @param upfInterface the interface to install
- * @throws UpfProgrammableException if the interface cannot be installed
- */
- void addInterface(UpfInterface upfInterface) throws UpfProgrammableException;
-
- /**
- * Remove a previously installed UPF interface from the target device.
- *
- * @param upfInterface the interface to be removed
- * @throws UpfProgrammableException if the interface cannot be found
- */
- void removeInterface(UpfInterface upfInterface) throws UpfProgrammableException;
-
- /**
- * Read the the given cell (Counter index) of the PDR counters from the given device.
- *
- * @param counterIdx The counter cell index from which to read
- * @return A structure containing ingress and egress packet and byte counts for the given
- * cellId.
- * @throws UpfProgrammableException if the cell ID is out of bounds
- */
- PdrStats readCounter(int counterIdx) throws UpfProgrammableException;
-
- /**
- * Return the number of PDR counter cells available. The number of cells in the ingress and
- * egress PDR counters are equivalent.
- *
- * @return PDR counter size
- */
- long pdrCounterSize();
-
- /**
- * Return the number of maximum number of table entries the FAR table supports.
- *
- * @return the number of FARs that can be installed
- */
- long farTableSize();
-
- /**
- * Return the total number of table entries the downlink and uplink PDR tables support. Both
- * tables support an equal number of entries, so the total is twice the size of either.
- *
- * @return the total number of PDRs that can be installed
- */
- long pdrTableSize();
-
- /**
- * Read the counter contents for all cell indices that are valid on the hardware switch.
- * {@code maxCounterId} parameter is used to limit the number of counters
- * retrieved from the UPF device. If the limit given is larger than the
- * physical limit, the physical limit will be used. A limit of -1 removes
- * limitations.
+ * Reads the UPF counter contents for all indices that are valid on the
+ * UPF-programmable device. {@code maxCounterId} parameter is used to limit
+ * the number of counters retrieved from the UPF. If the limit given is
+ * larger than the physical limit, the physical limit will be used.
+ * A limit of -1 removes limitations, and it is equivalent of calling
+ * {@link #readAll(UpfEntityType)} passing the {@code COUNTER} {@link UpfEntityType}.
*
* @param maxCounterId Maximum counter ID to retrieve from the UPF device.
- * @return A collection of counter values for all valid hardware counter cells
- * @throws UpfProgrammableException if the counters are unable to be read
+ * @return A collection of UPF counters for all valid hardware counter cells.
+ * @throws UpfProgrammableException if the counters are unable to be read.
*/
- Collection<PdrStats> readAllCounters(long maxCounterId) throws UpfProgrammableException;
+ Collection<UpfCounter> readCounters(long maxCounterId) throws UpfProgrammableException;
+
+ /**
+ * Deletes the given UPF entity from the UPF-programmable device.
+ *
+ * @param entity The UPF entity to be removed.
+ * @throws UpfProgrammableException if the given UPF entity is not found or
+ * the operation is not supported on the given UPF entity.
+ */
+ void delete(UpfEntity entity) throws UpfProgrammableException;
+
+ /**
+ * Deletes the given UPF entity from the UPF-programmable device.
+ *
+ * @param entityType The UPF entity type to be removed.
+ * @throws UpfProgrammableException if the given UPF entity is not found or
+ * the operation is not supported on the given UPF entity.
+ */
+ void deleteAll(UpfEntityType entityType) throws UpfProgrammableException;
+
+ /**
+ * Returns the total number of UPF entities of the given type supported by
+ * the UPF-programmable device. For entities that have a direction,returns
+ * the total amount of entities including both the downlink and the uplink
+ * directions.
+ * @param entityType The type of UPF programmable entities to retrieve the size from.
+ * @return The total number of supported UPF entities.
+ * @throws UpfProgrammableException if the operation is not supported on the given UPF entity.
+ */
+ long tableSize(UpfEntityType entityType) throws UpfProgrammableException;
/**
* Instructs the UPF-programmable device to use GTP-U extension PDU Session Container (PSC) when
* doing encap of downlink packets, with the given QoS Flow Identifier (QFI).
*
- * @param defaultQfi QFI to be used by default for all encapped packets.
* @throws UpfProgrammableException if operation is not available
*/
- // FIXME: remove once we expose QFI in logical pipeline
- // QFI should be set by the SMF using PFCP
- void enablePscEncap(int defaultQfi) throws UpfProgrammableException;
+ void enablePscEncap() throws UpfProgrammableException;
/**
- * Disable PSC encap previously enabled with {@link #enablePscEncap(int)}.
+ * Disable PSC encap previously enabled with {@link #enablePscEncap()}.
*
* @throws UpfProgrammableException if operation is not available
*/
- // FIXME: remove once we expose QFI in logical pipeline
- // QFI should be set by the SMF using PFCP
void disablePscEncap() throws UpfProgrammableException;
/**
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/package-info.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntity.java
similarity index 65%
rename from pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/package-info.java
rename to core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntity.java
index fe4c590..ad1fbaa 100644
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/package-info.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntity.java
@@ -14,7 +14,19 @@
* limitations under the License.
*/
+package org.onosproject.net.behaviour.upf;
+
+import com.google.common.annotations.Beta;
+
/**
- * Unit tests for UPF programmable behaviour.
+ * Abstraction of a UPF entity used to interact with the UPF-programmable device.
*/
-package org.onosproject.pipelines.fabric.impl.behaviour.upf;
+@Beta
+public interface UpfEntity {
+ /**
+ * Returns the type of this entity.
+ *
+ * @return entity type
+ */
+ UpfEntityType 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
new file mode 100644
index 0000000..7ec3b19
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfEntityType.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021-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.annotations.Beta;
+
+/**
+ * Type of UPF entity.
+ */
+@Beta
+public enum UpfEntityType {
+ INTERFACE("interface"),
+ TERMINATION_DOWNLINK("termination_downlink"),
+ TERMINATION_UPLINK("termination_uplink"),
+ SESSION_DOWNLINK("session_downlink"),
+ SESSION_UPLINK("session_downlink"),
+ TUNNEL_PEER("tunnel_peer"),
+ COUNTER("counter");
+
+ private final String humanReadableName;
+
+ UpfEntityType(String humanReadableName) {
+ this.humanReadableName = humanReadableName;
+ }
+
+ /**
+ * Returns a human readable representation of this UPF entity type (useful
+ * for logging).
+ *
+ * @return string
+ */
+ public String humanReadableName() {
+ return humanReadableName;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfInterface.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfInterface.java
index 3fee11a..f697d15 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfInterface.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfInterface.java
@@ -16,6 +16,7 @@
package org.onosproject.net.behaviour.upf;
+import com.google.common.annotations.Beta;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
@@ -26,7 +27,8 @@
/**
* A UPF device interface, such as a S1U or UE IP address pool.
*/
-public final class UpfInterface {
+@Beta
+public final class UpfInterface implements UpfEntity {
private final Ip4Prefix prefix;
private final Type type;
@@ -134,7 +136,6 @@
return type == Type.CORE;
}
-
/**
* Check if this UPF interface is for receiving buffered packets as they are released from the dbuf
* buffering device.
@@ -154,6 +155,11 @@
return this.prefix;
}
+ @Override
+ public UpfEntityType type() {
+ return UpfEntityType.INTERFACE;
+ }
+
public enum Type {
/**
* Unknown UPF interface 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 159adb0..052084e 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
@@ -30,13 +30,12 @@
public interface UpfProgrammable extends HandlerBehaviour, UpfDevice {
/**
* Apps are expected to call this method as the first one when they are ready
- * to install PDRs and FARs.
+ * to install any UPF entity.
*
* @return True if initialized, false otherwise.
*/
boolean init();
-
/**
* Checks if the given flow rule has been generated by this UPF behaviour.
*
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfProgrammableException.java b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfProgrammableException.java
index 7daa806..96f8c85 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfProgrammableException.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfProgrammableException.java
@@ -16,14 +16,20 @@
package org.onosproject.net.behaviour.upf;
+import com.google.common.annotations.Beta;
+
+import java.util.Optional;
+
/**
* An exception indicating a an error happened in the UPF programmable behaviour.
* Possible errors include the attempted insertion of a malformed flow rule, the
* reading or writing of an out-of-bounds counter cell, the deletion of a non-existent
* flow rule, and the attempted insertion of a flow rule into a full table.
*/
+@Beta
public class UpfProgrammableException extends Exception {
private final Type type;
+ private final UpfEntityType entityType;
public enum Type {
/**
@@ -31,13 +37,13 @@
*/
UNKNOWN,
/**
- * The target table is at capacity.
+ * The target entity is at capacity.
*/
- TABLE_EXHAUSTED,
+ ENTITY_EXHAUSTED,
/**
- * A provided counter cell index was out of range.
+ * A provided index was out of range.
*/
- COUNTER_INDEX_OUT_OF_RANGE,
+ ENTITY_OUT_OF_RANGE,
/**
* The UpfProgrammable implementation doesn't support the operation.
*/
@@ -52,6 +58,7 @@
public UpfProgrammableException(String message) {
super(message);
this.type = Type.UNKNOWN;
+ this.entityType = null;
}
/**
@@ -63,6 +70,20 @@
public UpfProgrammableException(String message, Type type) {
super(message);
this.type = type;
+ this.entityType = null;
+ }
+
+ /**
+ * Creates a new exception for the given message, type and entity type.
+ *
+ * @param message exception message
+ * @param type exception type
+ * @param entityType entity type
+ */
+ public UpfProgrammableException(String message, Type type, UpfEntityType entityType) {
+ super(message);
+ this.type = type;
+ this.entityType = entityType;
}
/**
@@ -73,4 +94,13 @@
public Type getType() {
return type;
}
+
+ /**
+ * Get the type of the entity that generated the exception.
+ *
+ * @return entity type
+ */
+ public Optional<UpfEntityType> getEntityType() {
+ return Optional.ofNullable(entityType);
+ }
}
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
new file mode 100644
index 0000000..3bc9a91
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationDownlink.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2021-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.annotations.Beta;
+import org.onlab.packet.Ip4Address;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A structure representing the UE Termination in the downlink direction on the
+ * UPF-programmable device.
+ * Provides means to configure the traffic behavior (e.g. set Traffic Class, GTP TEID, or QFI).
+ */
+@Beta
+public final class UpfTerminationDownlink implements UpfEntity {
+ // Match Keys
+ private final Ip4Address ueSessionId; // UE Session ID, use UE IP address to uniquely identify a session.
+ // Action parameters
+ private final Integer ctrId; // Counter ID unique to this UPF Termination Rule
+ private final Byte trafficClass;
+ private final Integer teid; // Tunnel Endpoint Identifier
+ private final Byte qfi; // QoS Flow Identifier
+ private final boolean dropping;
+
+ private UpfTerminationDownlink(Ip4Address ueSessionId, Integer ctrId, Byte trafficClass,
+ Integer teid, Byte qfi, boolean dropping) {
+ this.ueSessionId = ueSessionId;
+ this.ctrId = ctrId;
+ this.trafficClass = trafficClass;
+ this.teid = teid;
+ this.qfi = qfi;
+ this.dropping = dropping;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ UpfTerminationDownlink that = (UpfTerminationDownlink) obj;
+
+ // Safe comparisons between potentially null objects
+ return this.dropping == that.dropping &&
+ Objects.equals(this.ueSessionId, that.ueSessionId) &&
+ Objects.equals(this.ctrId, that.ctrId) &&
+ Objects.equals(this.trafficClass, that.trafficClass) &&
+ Objects.equals(this.teid, that.teid) &&
+ Objects.equals(this.qfi, that.qfi);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ueSessionId, ctrId, trafficClass, teid, qfi, dropping);
+ }
+
+ /**
+ * Get UE Session ID associated with UPF Termination rule.
+ *
+ * @return UE Session ID
+ */
+ public Ip4Address ueSessionId() {
+ return ueSessionId;
+ }
+
+ /**
+ * Get PDR Counter ID associated with UPF Termination rule.
+ *
+ * @return PDR counter cell ID
+ */
+ public Integer counterId() {
+ return ctrId;
+ }
+
+ /**
+ * Get Traffic Class set by this UPF Termination rule.
+ *
+ * @return Traffic Class
+ */
+ public Byte trafficClass() {
+ return trafficClass;
+ }
+
+ /**
+ * Get GTP TEID set by this UPF Termination rule.
+ *
+ * @return GTP tunnel ID
+ */
+ public Integer teid() {
+ return teid;
+ }
+
+ /**
+ * Get QoS Flow Identifier set by this UPF Termination rule.
+ *
+ * @return QoS Flow Identifier
+ */
+ public Byte qfi() {
+ return qfi;
+ }
+
+ /**
+ * True if this UPF Termination needs to drop traffic.
+ *
+ * @return true if the UPF Termination needs dropping.
+ */
+ public boolean needsDropping() {
+ return dropping;
+ }
+
+ @Override
+ public UpfEntityType type() {
+ return UpfEntityType.TERMINATION_DOWNLINK;
+ }
+
+ @Override
+ public String toString() {
+ return "TerminationUL{" + matchString() + "->" + actionString() + "}";
+ }
+
+ private String matchString() {
+ return "Match(ue_addr=" + this.ueSessionId() + ")";
+ }
+
+ private String actionString() {
+ return "(TEID=" + this.teid() +
+ ", CTR_ID=" + this.counterId() +
+ ", QFI=" + this.qfi() +
+ ", TC=" + this.trafficClass() +
+ ")";
+ }
+
+ public static class Builder {
+ private Ip4Address ueSessionId = null;
+ private Integer ctrId = null;
+ private Byte trafficClass = null;
+ private Integer teid = null;
+ private Byte qfi = null;
+ private boolean drop = false;
+
+ public Builder() {
+
+ }
+
+ /**
+ * Set the ID of the UE session.
+ *
+ * @param ueSessionId UE session ID
+ * @return This builder object
+ */
+ public Builder withUeSessionId(Ip4Address ueSessionId) {
+ this.ueSessionId = ueSessionId;
+ return this;
+ }
+
+ /**
+ * Set the dataplane counter cell ID.
+ *
+ * @param ctrId PDR counter cell ID
+ * @return This builder object
+ */
+ public Builder withCounterId(int ctrId) {
+ this.ctrId = ctrId;
+ return this;
+ }
+
+ /**
+ * Set the Traffic Class.
+ *
+ * @param trafficClass Traffic Class
+ * @return This builder object
+ */
+ public Builder withTrafficClass(byte trafficClass) {
+ this.trafficClass = trafficClass;
+ return this;
+ }
+
+ /**
+ * Set the identifier of the unidirectional GTP tunnel that should be used for the UE Session.
+ *
+ * @param teid tunnel ID
+ * @return This builder object
+ */
+ public Builder withTeid(Integer teid) {
+ this.teid = teid;
+ return this;
+ }
+
+ /**
+ * Set the QoS Flow Identifier.
+ *
+ * @param qfi GTP Tunnel QFI
+ * @return This builder object
+ */
+ public Builder withQfi(byte qfi) {
+ this.qfi = qfi;
+ return this;
+ }
+
+ /**
+ * Sets whether to drop downlink UPF termination traffic or not.
+ *
+ * @param drop True if request to buffer, false otherwise
+ * @return This builder object
+ */
+ public Builder needsDropping(boolean drop) {
+ this.drop = drop;
+ return this;
+ }
+
+
+ public UpfTerminationDownlink build() {
+ // Match fields must be provided
+ checkNotNull(ueSessionId, "UE session ID must be provided");
+
+ checkNotNull(ctrId, "Counter ID must be provided");
+ // TODO: should we verify that when dropping no other fields are provided
+ return new UpfTerminationDownlink(
+ this.ueSessionId, this.ctrId, this.trafficClass, this.teid,
+ this.qfi, 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
new file mode 100644
index 0000000..74dbc01
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/upf/UpfTerminationUplink.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2021-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.annotations.Beta;
+import org.onlab.packet.Ip4Address;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A structure representing the UE Termination in the uplink direction on the
+ * UPF-programmable device.
+ * Provides means to configure the traffic behavior (e.g. set Traffic Class).
+ */
+@Beta
+public final class UpfTerminationUplink implements UpfEntity {
+ // Match Keys
+ private final Ip4Address ueSessionId; // UE Session ID, use UE IP address to uniquely identify a session.
+ // Action parameters
+ private final Integer ctrId; // Counter ID unique to this UPF Termination Rule
+ private final Byte trafficClass;
+ private final boolean dropping;
+
+ private UpfTerminationUplink(Ip4Address ueSessionId, Integer ctrId, Byte trafficClass,
+ boolean dropping) {
+ this.ueSessionId = ueSessionId;
+ this.ctrId = ctrId;
+ this.trafficClass = trafficClass;
+ this.dropping = dropping;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ UpfTerminationUplink that = (UpfTerminationUplink) obj;
+
+ // Safe comparisons between potentially null objects
+ return this.dropping == that.dropping &&
+ Objects.equals(this.ueSessionId, that.ueSessionId) &&
+ Objects.equals(this.ctrId, that.ctrId) &&
+ Objects.equals(this.trafficClass, that.trafficClass);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ueSessionId, ctrId, trafficClass, dropping);
+ }
+
+ /**
+ * Get UE Session ID associated with UPF Termination rule.
+ *
+ * @return UE Session ID
+ */
+ public Ip4Address ueSessionId() {
+ return ueSessionId;
+ }
+
+ /**
+ * Get PDR Counter ID associated with UPF Termination rule.
+ *
+ * @return PDR counter cell ID
+ */
+ public Integer counterId() {
+ return ctrId;
+ }
+
+ /**
+ * Get Traffic Class set by this UPF Termination rule.
+ *
+ * @return Traffic Class
+ */
+ public Byte trafficClass() {
+ return trafficClass;
+ }
+
+ /**
+ * True if this UPF Termination needs to drop traffic.
+ *
+ * @return true if the UPF Termination needs dropping.
+ */
+ public boolean needsDropping() {
+ return dropping;
+ }
+
+ @Override
+ public UpfEntityType type() {
+ return UpfEntityType.TERMINATION_UPLINK;
+ }
+
+ @Override
+ public String toString() {
+ return "TerminationDL{" + matchString() + "->" + actionString() + "}";
+ }
+
+ private String matchString() {
+ return "Match(ue_addr=" + this.ueSessionId() + ")";
+ }
+
+ private String actionString() {
+ return "(CTR_ID=" + this.counterId() + ", TC=" + this.trafficClass() + ")";
+ }
+
+ public static class Builder {
+ private Ip4Address ueSessionId = null;
+ private Integer ctrId = null;
+ private Byte trafficClass = null;
+ private boolean dropping = false;
+
+ public Builder() {
+
+ }
+
+ /**
+ * Set the ID of the UE session.
+ *
+ * @param ueSessionId UE session ID
+ * @return This builder object
+ */
+ public Builder withUeSessionId(Ip4Address ueSessionId) {
+ this.ueSessionId = ueSessionId;
+ return this;
+ }
+
+ /**
+ * Set the dataplane counter cell ID.
+ *
+ * @param ctrId PDR counter cell ID
+ * @return This builder object
+ */
+ public Builder withCounterId(int ctrId) {
+ this.ctrId = ctrId;
+ return this;
+ }
+
+ /**
+ * Set the Traffic Class.
+ *
+ * @param trafficClass Traffic Class
+ * @return This builder object
+ */
+ public Builder withTrafficClass(byte trafficClass) {
+ this.trafficClass = trafficClass;
+ return this;
+ }
+
+ /**
+ * Sets whether to drop uplink UPF termination traffic or not.
+ *
+ * @param dropping True if request to buffer, false otherwise
+ * @return This builder object
+ */
+ public Builder needsDropping(boolean dropping) {
+ this.dropping = dropping;
+ return this;
+ }
+
+ public UpfTerminationUplink build() {
+ // Match fields must be provided
+ checkNotNull(ueSessionId, "UE session ID must be provided");
+
+ checkNotNull(ctrId, "Counter ID must be provided");
+ // TODO: should we verify that when dropping no other fields are provided
+ return new UpfTerminationUplink(
+ this.ueSessionId, this.ctrId, this.trafficClass, this.dropping);
+ }
+
+ }
+
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfManager.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfManager.java
index 7d1ee4e..e17b48e 100644
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfManager.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfManager.java
@@ -19,8 +19,6 @@
import org.onosproject.net.behaviour.inbandtelemetry.IntProgrammable;
import org.onosproject.net.behaviour.BngProgrammable;
-import org.onosproject.net.behaviour.upf.UpfProgrammable;
-import org.onosproject.pipelines.fabric.impl.behaviour.upf.FabricUpfProgrammable;
import org.onosproject.net.behaviour.Pipeliner;
import org.onosproject.net.pi.model.DefaultPiPipeconf;
import org.onosproject.net.pi.model.PiPipeconf;
@@ -101,11 +99,6 @@
if (profileName.endsWith(BNG_PROFILE_SUFFIX)) {
pipeconfBuilder.addBehaviour(BngProgrammable.class, FabricBngProgrammable.class);
}
- // Add UpfProgrammable behavior for UPF-enabled pipelines.
- if (profileName.contains(UPF_PROFILE_SUFFIX) ||
- profileName.endsWith(FULL_PROFILE_SUFFIX)) {
- pipeconfBuilder.addBehaviour(UpfProgrammable.class, FabricUpfProgrammable.class);
- }
return pipeconfBuilder.build();
}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/cli/ReadInternalUpfStoreCommand.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/cli/ReadInternalUpfStoreCommand.java
deleted file mode 100644
index 31dd975..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/cli/ReadInternalUpfStoreCommand.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.cli;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.pipelines.fabric.impl.behaviour.upf.FabricUpfStore;
-import org.onosproject.pipelines.fabric.impl.behaviour.upf.UpfRuleIdentifier;
-
-import java.util.Map;
-
-/**
- * Read internal UPF store of fabric.
- */
-@Service
-@Command(scope = "fabric", name = "upf-read-internal-store",
- description = "Print internal UPF stores")
-public class ReadInternalUpfStoreCommand extends AbstractShellCommand {
- @Option(name = "-v", aliases = "--verbose",
- description = "Print more detail of each entry",
- required = false, multiValued = false)
- private boolean verbose = false;
-
- @Override
- protected void doExecute() {
- FabricUpfStore upfStore = get(FabricUpfStore.class);
-
- if (upfStore == null) {
- print("Error: FabricUpfStore is null");
- return;
- }
-
- Map<Integer, UpfRuleIdentifier> reverseFarIdMap = upfStore.getReverseFarIdMap();
- print("reverseFarIdMap size: " + reverseFarIdMap.size());
- if (verbose) {
- reverseFarIdMap.entrySet().forEach(entry -> print(entry.toString()));
- }
- }
-}
\ No newline at end of file
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/cli/package-info.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/cli/package-info.java
deleted file mode 100644
index f78dd7a..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/cli/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2021-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.
- */
-
-/**
- * CLI commands for fabric UPF.
- */
-package org.onosproject.pipelines.fabric.impl.behaviour.cli;
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/DistributedFabricUpfStore.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/DistributedFabricUpfStore.java
deleted file mode 100644
index 7045c2d..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/DistributedFabricUpfStore.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import com.google.common.hash.HashCode;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
-import org.onlab.util.ImmutableByteSequence;
-import org.onlab.util.KryoNamespace;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.StorageService;
-import org.onosproject.store.service.WallClockTimestamp;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * Distributed implementation of FabricUpfStore.
- */
-@Component(immediate = true, service = FabricUpfStore.class)
-public final class DistributedFabricUpfStore implements FabricUpfStore {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY)
- protected StorageService storageService;
-
- protected static final String FAR_ID_MAP_NAME = "fabric-upf-far-id";
- protected static final KryoNamespace.Builder SERIALIZER = KryoNamespace.newBuilder()
- .register(KryoNamespaces.API)
- .register(UpfRuleIdentifier.class);
-
- // EC map to remember the mapping far_id -> rule_id this is mostly used during reads,
- // it can be definitely removed by simplifying the logical pipeline
- protected EventuallyConsistentMap<Integer, UpfRuleIdentifier> reverseFarIdMap;
-
- @Activate
- protected void activate() {
- // Allow unit test to inject reverseFarIdMap here.
- if (storageService != null) {
- this.reverseFarIdMap = storageService.<Integer, UpfRuleIdentifier>eventuallyConsistentMapBuilder()
- .withName(FAR_ID_MAP_NAME)
- .withSerializer(SERIALIZER)
- .withTimestampProvider((k, v) -> new WallClockTimestamp())
- .build();
- }
-
- log.info("Started");
- }
-
- @Deactivate
- protected void deactivate() {
- reverseFarIdMap.destroy();
-
- log.info("Stopped");
- }
-
- @Override
- public void reset() {
- reverseFarIdMap.clear();
- }
-
- @Override
- public Map<Integer, UpfRuleIdentifier> getReverseFarIdMap() {
- return reverseFarIdMap.entrySet().stream()
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
- }
-
- @Override
- public int globalFarIdOf(UpfRuleIdentifier farIdPair) {
- int globalFarId = getGlobalFarIdOf(farIdPair);
- reverseFarIdMap.put(globalFarId, farIdPair);
- log.info("{} translated to GlobalFarId={}", farIdPair, globalFarId);
- return globalFarId;
- }
-
- @Override
- public int removeGlobalFarId(UpfRuleIdentifier farIdPair) {
- int globalFarId = getGlobalFarIdOf(farIdPair);
- reverseFarIdMap.remove(globalFarId);
- return globalFarId;
- }
-
- @Override
- public int globalFarIdOf(ImmutableByteSequence pfcpSessionId, int sessionLocalFarId) {
- UpfRuleIdentifier farId = new UpfRuleIdentifier(pfcpSessionId, sessionLocalFarId);
- return globalFarIdOf(farId);
- }
-
- @Override
- public int removeGlobalFarId(ImmutableByteSequence pfcpSessionId, int sessionLocalFarId) {
- UpfRuleIdentifier farId = new UpfRuleIdentifier(pfcpSessionId, sessionLocalFarId);
- return removeGlobalFarId(farId);
- }
-
- @Override
- public UpfRuleIdentifier localFarIdOf(int globalFarId) {
- return reverseFarIdMap.get(globalFarId);
- }
-
- // Compute global far id by hashing the pfcp session id and the session local far
- private int getGlobalFarIdOf(UpfRuleIdentifier farIdPair) {
- HashFunction hashFunction = Hashing.murmur3_32();
- HashCode hashCode = hashFunction.newHasher()
- .putInt(farIdPair.getSessionLocalId())
- .putBytes(farIdPair.getPfcpSessionId().asArray())
- .hash();
- return hashCode.asInt();
- }
-
-}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfProgrammable.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfProgrammable.java
deleted file mode 100644
index 310f28d..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfProgrammable.java
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import org.onlab.packet.Ip4Prefix;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.drivers.p4runtime.AbstractP4RuntimeHandlerBehaviour;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.upf.ForwardingActionRule;
-import org.onosproject.net.behaviour.upf.PacketDetectionRule;
-import org.onosproject.net.behaviour.upf.PdrStats;
-import org.onosproject.net.behaviour.upf.UpfInterface;
-import org.onosproject.net.behaviour.upf.UpfProgrammable;
-import org.onosproject.net.behaviour.upf.UpfProgrammableException;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.criteria.PiCriterion;
-import org.onosproject.net.packet.DefaultOutboundPacket;
-import org.onosproject.net.packet.OutboundPacket;
-import org.onosproject.net.packet.PacketService;
-import org.onosproject.net.pi.model.PiCounterId;
-import org.onosproject.net.pi.model.PiCounterModel;
-import org.onosproject.net.pi.model.PiTableId;
-import org.onosproject.net.pi.model.PiTableModel;
-import org.onosproject.net.pi.runtime.PiCounterCell;
-import org.onosproject.net.pi.runtime.PiCounterCellHandle;
-import org.onosproject.net.pi.runtime.PiCounterCellId;
-import org.onosproject.pipelines.fabric.impl.FabricPipeconfLoader;
-import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-
-import static org.onosproject.net.behaviour.upf.UpfProgrammableException.Type.UNSUPPORTED_OPERATION;
-import static org.onosproject.net.pi.model.PiCounterType.INDIRECT;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_EGRESS_SPGW_PDR_COUNTER;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_DOWNLINK_PDRS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_FARS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_INTERFACES;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_PDR_COUNTER;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_UPLINK_PDRS;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_FAR_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_GTPU_IS_VALID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_HAS_QFI;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_IPV4_DST_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_QFI;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_TEID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_TUNNEL_IPV4_DST;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_UE_ADDR;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_QFI;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FALSE;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.TRUE;
-
-/**
- * Implementation of a UPF programmable device behavior.
- */
-public class FabricUpfProgrammable extends AbstractP4RuntimeHandlerBehaviour
- implements UpfProgrammable {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
- private static final int DEFAULT_PRIORITY = 128;
- private static final long DEFAULT_P4_DEVICE_ID = 1;
-
- protected FlowRuleService flowRuleService;
- protected PacketService packetService;
- protected FabricUpfStore fabricUpfStore;
- protected FabricUpfTranslator upfTranslator;
-
- private long farTableSize;
- private long encappedPdrTableSize;
- private long unencappedPdrTableSize;
- private long pdrCounterSize;
-
- private ApplicationId appId;
-
- @Override
- protected boolean setupBehaviour(String opName) {
- // Already initialized.
- if (appId != null) {
- return true;
- }
-
- if (!super.setupBehaviour(opName)) {
- return false;
- }
-
- if (!computeHardwareResourceSizes()) {
- // error message will be printed by computeHardwareResourceSizes()
- return false;
- }
-
- flowRuleService = handler().get(FlowRuleService.class);
- packetService = handler().get(PacketService.class);
- fabricUpfStore = handler().get(FabricUpfStore.class);
- upfTranslator = new FabricUpfTranslator(fabricUpfStore);
- final CoreService coreService = handler().get(CoreService.class);
- appId = coreService.getAppId(FabricPipeconfLoader.PIPELINE_APP_NAME_UPF);
- if (appId == null) {
- log.warn("Application ID is null. Cannot initialize behaviour.");
- return false;
- }
-
- var capabilities = new FabricCapabilities(pipeconf);
- if (!capabilities.supportUpf()) {
- log.warn("Pipeconf {} on {} does not support UPF capabilities, " +
- "cannot perform {}",
- pipeconf.id(), deviceId, opName);
- return false;
- }
- return true;
- }
-
- @Override
- public boolean init() {
- if (setupBehaviour("init()")) {
- log.info("UpfProgrammable initialized for appId {} and deviceId {}", appId, deviceId);
- return true;
- }
- return false;
- }
-
- @Override
- public boolean fromThisUpf(FlowRule flowRule) {
- return flowRule.deviceId().equals(this.deviceId) &&
- flowRule.appId() == appId.id();
- }
-
- /**
- * Grab the capacities for the PDR and FAR tables from the pipeconf. Runs only once, on initialization.
- *
- * @return true if resource is fetched successfully, false otherwise.
- * @throws IllegalStateException when FAR or PDR table can't be found in the pipeline model.
- */
- private boolean computeHardwareResourceSizes() {
- long farTableSize = 0;
- long encappedPdrTableSize = 0;
- long unencappedPdrTableSize = 0;
-
- // Get table sizes of interest
- for (PiTableModel piTable : pipeconf.pipelineModel().tables()) {
- if (piTable.id().equals(FABRIC_INGRESS_SPGW_UPLINK_PDRS)) {
- encappedPdrTableSize = piTable.maxSize();
- } else if (piTable.id().equals(FABRIC_INGRESS_SPGW_DOWNLINK_PDRS)) {
- unencappedPdrTableSize = piTable.maxSize();
- } else if (piTable.id().equals(FABRIC_INGRESS_SPGW_FARS)) {
- farTableSize = piTable.maxSize();
- }
- }
- if (encappedPdrTableSize == 0) {
- throw new IllegalStateException("Unable to find uplink PDR table in pipeline model.");
- }
- if (unencappedPdrTableSize == 0) {
- throw new IllegalStateException("Unable to find downlink PDR table in pipeline model.");
- }
- if (encappedPdrTableSize != unencappedPdrTableSize) {
- log.warn("The uplink and downlink PDR tables don't have equal sizes! Using the minimum of the two.");
- }
- if (farTableSize == 0) {
- throw new IllegalStateException("Unable to find FAR table in pipeline model.");
- }
- // Get counter sizes of interest
- long ingressCounterSize = 0;
- long egressCounterSize = 0;
- for (PiCounterModel piCounter : pipeconf.pipelineModel().counters()) {
- if (piCounter.id().equals(FABRIC_INGRESS_SPGW_PDR_COUNTER)) {
- ingressCounterSize = piCounter.size();
- } else if (piCounter.id().equals(FABRIC_EGRESS_SPGW_PDR_COUNTER)) {
- egressCounterSize = piCounter.size();
- }
- }
- if (ingressCounterSize != egressCounterSize) {
- log.warn("PDR ingress and egress counter sizes are not equal! Using the minimum of the two.");
- }
- this.farTableSize = farTableSize;
- this.encappedPdrTableSize = encappedPdrTableSize;
- this.unencappedPdrTableSize = unencappedPdrTableSize;
- this.pdrCounterSize = Math.min(ingressCounterSize, egressCounterSize);
- return true;
- }
-
- @Override
- public void enablePscEncap(int defaultQfi) throws UpfProgrammableException {
- throw new UpfProgrammableException("PSC encap is not supported in fabric-v1model",
- UNSUPPORTED_OPERATION);
- }
-
- @Override
- public void disablePscEncap() throws UpfProgrammableException {
- throw new UpfProgrammableException("PSC encap is not supported in fabric-v1model",
- UNSUPPORTED_OPERATION);
- }
-
- @Override
- public void sendPacketOut(ByteBuffer data) {
- if (!setupBehaviour("sendPacketOut()")) {
- return;
- }
- final OutboundPacket pkt = new DefaultOutboundPacket(
- deviceId,
- // Use TABLE logical port to have pkt routed via pipeline tables.
- DefaultTrafficTreatment.builder()
- .setOutput(PortNumber.TABLE)
- .build(),
- data);
- packetService.emit(pkt);
- }
-
- @Override
- public void cleanUp() {
- if (!setupBehaviour("cleanUp()")) {
- return;
- }
- log.info("Clearing all UPF-related table entries.");
- // Getting flow entries by device ID and filtering by Application ID
- // is more efficient than getting by Application ID and filtering for a
- // device ID.
- List<FlowEntry> flowEntriesToRemove = StreamSupport.stream(
- flowRuleService.getFlowEntries(deviceId).spliterator(), false)
- .filter(flowEntry -> flowEntry.appId() == appId.id()).collect(Collectors.toList());
- flowRuleService.removeFlowRules(flowEntriesToRemove.toArray(new FlowRule[0]));
- fabricUpfStore.reset();
- }
-
- @Override
- public void clearInterfaces() {
- if (!setupBehaviour("clearInterfaces()")) {
- return;
- }
- log.info("Clearing all UPF interfaces.");
- for (FlowRule entry : flowRuleService.getFlowEntries(deviceId)) {
- if (upfTranslator.isFabricInterface(entry)) {
- flowRuleService.removeFlowRules(entry);
- }
- }
- }
-
- @Override
- public void clearFlows() {
- if (!setupBehaviour("clearFlows()")) {
- return;
- }
- log.info("Clearing all UE sessions.");
- int pdrsCleared = 0;
- int farsCleared = 0;
- for (FlowRule entry : flowRuleService.getFlowEntries(deviceId)) {
- if (upfTranslator.isFabricPdr(entry)) {
- pdrsCleared++;
- flowRuleService.removeFlowRules(entry);
- } else if (upfTranslator.isFabricFar(entry)) {
- farsCleared++;
- flowRuleService.removeFlowRules(entry);
- }
- }
- log.info("Cleared {} PDRs and {} FARS.", pdrsCleared, farsCleared);
- }
-
-
- @Override
- public Collection<PdrStats> readAllCounters(long maxCounterId) {
- if (!setupBehaviour("readAllCounters()")) {
- return null;
- }
-
- long counterSize = pdrCounterSize();
- if (maxCounterId != -1) {
- counterSize = Math.min(maxCounterId, counterSize);
- }
-
- // Prepare PdrStats object builders, one for each counter ID currently in use
- Map<Integer, PdrStats.Builder> pdrStatBuilders = Maps.newHashMap();
- for (int cellId = 0; cellId < counterSize; cellId++) {
- pdrStatBuilders.put(cellId, PdrStats.builder().withCellId(cellId));
- }
-
- // Generate the counter cell IDs.
- Set<PiCounterId> counterIds = ImmutableSet.of(
- FABRIC_INGRESS_SPGW_PDR_COUNTER,
- FABRIC_EGRESS_SPGW_PDR_COUNTER
- );
-
- // Query the device.
- Collection<PiCounterCell> counterEntryResponse = client.read(
- DEFAULT_P4_DEVICE_ID, pipeconf)
- .counterCells(counterIds)
- .submitSync()
- .all(PiCounterCell.class);
-
- // Process response.
- counterEntryResponse.forEach(counterCell -> {
- if (counterCell.cellId().counterType() != INDIRECT) {
- log.warn("Invalid counter data type {}, skipping", counterCell.cellId().counterType());
- return;
- }
- if (!pdrStatBuilders.containsKey((int) counterCell.cellId().index())) {
- // Most likely Up4config.maxUes() is set to a value smaller than what the switch
- // pipeline can hold.
- log.debug("Unrecognized index {} when reading all counters, " +
- "that's expected if we are manually limiting maxUes", counterCell);
- return;
- }
- PdrStats.Builder statsBuilder = pdrStatBuilders.get((int) counterCell.cellId().index());
- if (counterCell.cellId().counterId().equals(FABRIC_INGRESS_SPGW_PDR_COUNTER)) {
- statsBuilder.setIngress(counterCell.data().packets(),
- counterCell.data().bytes());
- } else if (counterCell.cellId().counterId().equals(FABRIC_EGRESS_SPGW_PDR_COUNTER)) {
- statsBuilder.setEgress(counterCell.data().packets(),
- counterCell.data().bytes());
- } else {
- log.warn("Unrecognized counter ID {}, skipping", counterCell);
- }
- });
-
- return pdrStatBuilders
- .values()
- .stream()
- .map(PdrStats.Builder::build)
- .collect(Collectors.toList());
- }
-
- @Override
- public long pdrCounterSize() {
- if (!setupBehaviour("pdrCounterSize()")) {
- return -1;
- }
- return pdrCounterSize;
- }
-
- @Override
- public long farTableSize() {
- if (!setupBehaviour("farTableSize()")) {
- return -1;
- }
- return farTableSize;
- }
-
- @Override
- public long pdrTableSize() {
- if (!setupBehaviour("pdrTableSize()")) {
- return -1;
- }
- return Math.min(encappedPdrTableSize, unencappedPdrTableSize) * 2;
- }
-
- @Override
- public PdrStats readCounter(int cellId) throws UpfProgrammableException {
- if (!setupBehaviour("readCounter()")) {
- return null;
- }
- if (cellId >= pdrCounterSize() || cellId < 0) {
- throw new UpfProgrammableException("Requested PDR counter cell index is out of bounds.",
- UpfProgrammableException.Type.COUNTER_INDEX_OUT_OF_RANGE);
- }
- PdrStats.Builder stats = PdrStats.builder().withCellId(cellId);
-
- // Make list of cell handles we want to read.
- List<PiCounterCellHandle> counterCellHandles = List.of(
- PiCounterCellHandle.of(deviceId,
- PiCounterCellId.ofIndirect(FABRIC_INGRESS_SPGW_PDR_COUNTER, cellId)),
- PiCounterCellHandle.of(deviceId,
- PiCounterCellId.ofIndirect(FABRIC_EGRESS_SPGW_PDR_COUNTER, cellId)));
-
- // Query the device.
- Collection<PiCounterCell> counterEntryResponse = client.read(
- DEFAULT_P4_DEVICE_ID, pipeconf)
- .handles(counterCellHandles).submitSync()
- .all(PiCounterCell.class);
-
- // Process response.
- counterEntryResponse.forEach(counterCell -> {
- if (counterCell.cellId().counterType() != INDIRECT) {
- log.warn("Invalid counter data type {}, skipping", counterCell.cellId().counterType());
- return;
- }
- if (cellId != counterCell.cellId().index()) {
- log.warn("Unrecognized counter index {}, skipping", counterCell);
- return;
- }
- if (counterCell.cellId().counterId().equals(FABRIC_INGRESS_SPGW_PDR_COUNTER)) {
- stats.setIngress(counterCell.data().packets(), counterCell.data().bytes());
- } else if (counterCell.cellId().counterId().equals(FABRIC_EGRESS_SPGW_PDR_COUNTER)) {
- stats.setEgress(counterCell.data().packets(), counterCell.data().bytes());
- } else {
- log.warn("Unrecognized counter ID {}, skipping", counterCell);
- }
- });
- return stats.build();
- }
-
-
- @Override
- public void addPdr(PacketDetectionRule pdr) throws UpfProgrammableException {
- if (!setupBehaviour("addPdr()")) {
- return;
- }
- if (pdr.counterId() >= pdrCounterSize() || pdr.counterId() < 0) {
- throw new UpfProgrammableException("Counter cell index referenced by PDR is out of bounds.",
- UpfProgrammableException.Type.COUNTER_INDEX_OUT_OF_RANGE);
- }
- FlowRule fabricPdr = upfTranslator.pdrToFabricEntry(pdr, deviceId, appId, DEFAULT_PRIORITY);
- log.info("Installing {}", pdr.toString());
- flowRuleService.applyFlowRules(fabricPdr);
- log.debug("PDR added with flowID {}", fabricPdr.id().value());
- }
-
-
- @Override
- public void addFar(ForwardingActionRule far) throws UpfProgrammableException {
- if (!setupBehaviour("addFar()")) {
- return;
- }
- FlowRule fabricFar = upfTranslator.farToFabricEntry(far, deviceId, appId, DEFAULT_PRIORITY);
- log.info("Installing {}", far.toString());
- flowRuleService.applyFlowRules(fabricFar);
- log.debug("FAR added with flowID {}", fabricFar.id().value());
- }
-
- @Override
- public void addInterface(UpfInterface upfInterface) throws UpfProgrammableException {
- if (!setupBehaviour("addInterface()")) {
- return;
- }
- FlowRule flowRule = upfTranslator.interfaceToFabricEntry(upfInterface, deviceId, appId, DEFAULT_PRIORITY);
- log.info("Installing {}", upfInterface);
- flowRuleService.applyFlowRules(flowRule);
- log.debug("Interface added with flowID {}", flowRule.id().value());
- // By default we enable UE-to-UE communication on the UE subnet identified by the CORE interface.
- // TODO: allow enabling/disabling UE-to-UE via netcfg or other API.
- log.warn("UE-to-UE traffic is not supported in fabric-v1model");
- }
-
- private boolean removeEntry(PiCriterion match, PiTableId tableId, boolean failSilent)
- throws UpfProgrammableException {
- FlowRule entry = DefaultFlowRule.builder()
- .forDevice(deviceId).fromApp(appId).makePermanent()
- .forTable(tableId)
- .withSelector(DefaultTrafficSelector.builder().matchPi(match).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
- try {
- flowRuleService.removeFlowRules(entry);
- // TODO in future we may need to send other notifications to the pfcp agent
- //if (!failSilent) {
- // throw new UpfProgrammableException("Match criterion " + match.toString() +
- // " not found in table " + tableId.toString());
- //}
- return true;
- } catch (Exception e) {
- log.error("Exception thrown while removing flows", e);
- }
- // Assumes that the ONOS state is ok and the pfcp agent
- // is not asking to remove wrong flows
- if (!failSilent) {
- throw new UpfProgrammableException("Unable to remove FlowRule with match criterion " + match.toString() +
- " in table " + tableId.toString());
- }
- return false;
- }
-
- @Override
- public Collection<PacketDetectionRule> getPdrs() throws UpfProgrammableException {
- if (!setupBehaviour("getPdrs()")) {
- return null;
- }
- ArrayList<PacketDetectionRule> pdrs = new ArrayList<>();
- for (FlowRule flowRule : flowRuleService.getFlowEntries(deviceId)) {
- if (upfTranslator.isFabricPdr(flowRule)) {
- pdrs.add(upfTranslator.fabricEntryToPdr(flowRule));
- }
- }
- return pdrs;
- }
-
- @Override
- public Collection<ForwardingActionRule> getFars() throws UpfProgrammableException {
- if (!setupBehaviour("getFars()")) {
- return null;
- }
- ArrayList<ForwardingActionRule> fars = new ArrayList<>();
- for (FlowRule flowRule : flowRuleService.getFlowEntries(deviceId)) {
- if (upfTranslator.isFabricFar(flowRule)) {
- fars.add(upfTranslator.fabricEntryToFar(flowRule));
- }
- }
- return fars;
- }
-
- @Override
- public Collection<UpfInterface> getInterfaces() throws UpfProgrammableException {
- if (!setupBehaviour("getInterfaces()")) {
- return null;
- }
- ArrayList<UpfInterface> ifaces = new ArrayList<>();
- for (FlowRule flowRule : flowRuleService.getFlowEntries(deviceId)) {
- if (upfTranslator.isFabricInterface(flowRule)) {
- ifaces.add(upfTranslator.fabricEntryToInterface(flowRule));
- }
- }
- return ifaces;
- }
-
- @Override
- public void removePdr(PacketDetectionRule pdr) throws UpfProgrammableException {
- if (!setupBehaviour("removePdr()")) {
- return;
- }
- final PiCriterion match;
- final PiTableId tableId;
- if (pdr.matchesEncapped()) {
- PiCriterion.Builder criterionBuilder = PiCriterion.builder()
- .matchExact(HDR_TEID, pdr.teid().asArray())
- .matchExact(HDR_TUNNEL_IPV4_DST, pdr.tunnelDest().toInt());
- if (pdr.matchQfi()) {
- criterionBuilder.matchExact(HDR_HAS_QFI, TRUE);
- criterionBuilder.matchExact(HDR_QFI, pdr.qfi());
- } else {
- criterionBuilder.matchExact(HDR_HAS_QFI, FALSE);
- criterionBuilder.matchExact(HDR_QFI, DEFAULT_QFI);
- }
- match = criterionBuilder.build();
- tableId = FABRIC_INGRESS_SPGW_UPLINK_PDRS;
- } else {
- match = PiCriterion.builder()
- .matchExact(HDR_UE_ADDR, pdr.ueAddress().toInt())
- .build();
- tableId = FABRIC_INGRESS_SPGW_DOWNLINK_PDRS;
- }
- log.info("Removing {}", pdr.toString());
- removeEntry(match, tableId, false);
- }
-
- @Override
- public void removeFar(ForwardingActionRule far) throws UpfProgrammableException {
- if (!setupBehaviour("removeFar()")) {
- return;
- }
- log.info("Removing {}", far.toString());
-
- PiCriterion match = PiCriterion.builder()
- .matchExact(HDR_FAR_ID, fabricUpfStore.removeGlobalFarId(far.sessionId(), far.farId()))
- .build();
-
- removeEntry(match, FABRIC_INGRESS_SPGW_FARS, false);
- }
-
- @Override
- public void removeInterface(UpfInterface upfInterface) throws UpfProgrammableException {
- if (!setupBehaviour("removeInterface()")) {
- return;
- }
- Ip4Prefix ifacePrefix = upfInterface.getPrefix();
- // If it isn't a core interface (so it is either access/dbuf or unknown), try removing first
- // access/dbuf interfaces and then fall through in the next step where we try to remove the core flow
- if (!upfInterface.isCore()) {
- PiCriterion match1 = PiCriterion.builder()
- .matchLpm(HDR_IPV4_DST_ADDR, ifacePrefix.address().toInt(),
- ifacePrefix.prefixLength())
- .matchExact(HDR_GTPU_IS_VALID, 1)
- .build();
- // removeEntry does return false only for severe issues, before we had
- // a safe fall through. This part should not be affected since core and access
- // flows are different in the match keys and should not result in wrong removal
- removeEntry(match1, FABRIC_INGRESS_SPGW_INTERFACES, true);
- }
- // This additional step might be also needed in case of unknown interfaces
- PiCriterion match2 = PiCriterion.builder()
- .matchLpm(HDR_IPV4_DST_ADDR, ifacePrefix.address().toInt(),
- ifacePrefix.prefixLength())
- .matchExact(HDR_GTPU_IS_VALID, 0)
- .build();
- removeEntry(match2, FABRIC_INGRESS_SPGW_INTERFACES, false);
- }
-}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfStore.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfStore.java
deleted file mode 100644
index 8e9e92b..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfStore.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.onlab.util.ImmutableByteSequence;
-
-import java.util.Map;
-
-/**
- * Stores state required for translation of UPF entities to pipeline-specific ones.
- */
-public interface FabricUpfStore {
- /**
- * Clear all state associated with translation.
- */
- void reset();
-
- /**
- * Returns the reverseFarIdMap.
- *
- * @return the farIdMap.
- */
- Map<Integer, UpfRuleIdentifier> getReverseFarIdMap();
-
- /**
- * Get a globally unique integer identifier for the FAR identified by the given (Session ID, Far
- * ID) pair.
- *
- * @param farIdPair a RuleIdentifier instance uniquely identifying the FAR
- * @return A globally unique integer identifier
- */
- int globalFarIdOf(UpfRuleIdentifier farIdPair);
-
- /**
- * Remove the global far id from the system.
- *
- * @param farIdPair a RuleIdentifier instance uniquely identifying the FAR
- * @return A globally unique integer identifier
- */
- int removeGlobalFarId(UpfRuleIdentifier farIdPair);
-
- /**
- * Get a globally unique integer identifier for the FAR identified by the given (Session ID, Far
- * ID) pair.
- *
- * @param pfcpSessionId The ID of the PFCP session that produced the FAR ID.
- * @param sessionLocalFarId The FAR ID.
- * @return A globally unique integer identifier
- */
- int globalFarIdOf(ImmutableByteSequence pfcpSessionId, int sessionLocalFarId);
-
- /**
- * Remove the global far id from the system.
- *
- * @param pfcpSessionId The ID of the PFCP session that produced the FAR ID.
- * @param sessionLocalFarId The FAR ID.
- * @return A globally unique integer identifier
- */
- int removeGlobalFarId(ImmutableByteSequence pfcpSessionId, int sessionLocalFarId);
-
- /**
- * Get the corresponding PFCP session ID and session-local FAR ID from a globally unique FAR ID,
- * or return null if no such mapping is found.
- *
- * @param globalFarId globally unique FAR ID
- * @return the corresponding PFCP session ID and session-local FAR ID, as a RuleIdentifier
- */
- UpfRuleIdentifier localFarIdOf(int globalFarId);
-}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslator.java
deleted file mode 100644
index f2e7584..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslator.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.apache.commons.lang3.tuple.Pair;
-import org.onlab.packet.Ip4Address;
-import org.onlab.util.ImmutableByteSequence;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.behaviour.upf.ForwardingActionRule;
-import org.onosproject.net.behaviour.upf.GtpTunnel;
-import org.onosproject.net.behaviour.upf.PacketDetectionRule;
-import org.onosproject.net.behaviour.upf.UpfInterface;
-import org.onosproject.net.behaviour.upf.UpfProgrammableException;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.criteria.PiCriterion;
-import org.onosproject.net.pi.model.PiActionId;
-import org.onosproject.net.pi.model.PiTableId;
-import org.onosproject.net.pi.runtime.PiAction;
-import org.onosproject.net.pi.runtime.PiActionParam;
-import org.onosproject.net.pi.runtime.PiTableAction;
-
-import java.util.Arrays;
-
-import static org.onosproject.pipelines.fabric.FabricConstants.CTR_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.DROP;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_DOWNLINK_PDRS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_FARS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_INTERFACES;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_DBUF_FAR;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_IFACE;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_NORMAL_FAR;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_PDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_PDR_QOS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_TUNNEL_FAR;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_UPLINK_PDRS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FAR_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_FAR_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_GTPU_IS_VALID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_HAS_QFI;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_IPV4_DST_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_QFI;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_TEID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_TUNNEL_IPV4_DST;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_UE_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.NEEDS_GTPU_DECAP;
-import static org.onosproject.pipelines.fabric.FabricConstants.NEEDS_QFI_PUSH;
-import static org.onosproject.pipelines.fabric.FabricConstants.NOTIFY_CP;
-import static org.onosproject.pipelines.fabric.FabricConstants.QFI;
-import static org.onosproject.pipelines.fabric.FabricConstants.SLICE_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.SRC_IFACE;
-import static org.onosproject.pipelines.fabric.FabricConstants.TC;
-import static org.onosproject.pipelines.fabric.FabricConstants.TEID;
-import static org.onosproject.pipelines.fabric.FabricConstants.TUNNEL_DST_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.TUNNEL_SRC_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.TUNNEL_SRC_PORT;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_QFI;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_SLICE_ID;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_TC;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FALSE;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.TRUE;
-
-/**
- * Provides logic to translate UPF entities into pipeline-specific ones and vice-versa.
- * Implementation should be stateless, with all state delegated to FabricUpfStore.
- */
-public class FabricUpfTranslator {
-
- // UPF related constants
- public static final int INTERFACE_ACCESS = 1;
- public static final int INTERFACE_CORE = 2;
- public static final int INTERFACE_DBUF = 3;
-
- private final FabricUpfStore fabricUpfStore;
-
- public FabricUpfTranslator(FabricUpfStore fabricUpfStore) {
- this.fabricUpfStore = fabricUpfStore;
- }
-
- /**
- * Returns true if the given table entry is a Packet Detection Rule from the physical fabric pipeline, and
- * false otherwise.
- *
- * @param entry the entry that may or may not be a fabric.p4 PDR
- * @return true if the entry is a fabric.p4 PDR
- */
- public boolean isFabricPdr(FlowRule entry) {
- return entry.table().equals(FABRIC_INGRESS_SPGW_UPLINK_PDRS)
- || entry.table().equals(FABRIC_INGRESS_SPGW_DOWNLINK_PDRS);
- }
-
- /**
- * Returns true if the given table entry is a Forwarding Action Rule from the physical fabric pipeline, and
- * false otherwise.
- *
- * @param entry the entry that may or may not be a fabric.p4 FAR
- * @return true if the entry is a fabric.p4 FAR
- */
- public boolean isFabricFar(FlowRule entry) {
- return entry.table().equals(FABRIC_INGRESS_SPGW_FARS);
- }
-
- /**
- * Returns true if the given table entry is an interface table entry from the fabric.p4 physical pipeline, and
- * false otherwise.
- *
- * @param entry the entry that may or may not be a fabric.p4 UPF interface
- * @return true if the entry is a fabric.p4 UPF interface
- */
- public boolean isFabricInterface(FlowRule entry) {
- return entry.table().equals(FABRIC_INGRESS_SPGW_INTERFACES);
- }
-
-
- /**
- * Translate a fabric.p4 PDR table entry to a PacketDetectionRule instance for easier handling.
- *
- * @param entry the fabric.p4 entry to translate
- * @return the corresponding PacketDetectionRule
- * @throws UpfProgrammableException if the entry cannot be translated
- */
- public PacketDetectionRule fabricEntryToPdr(FlowRule entry)
- throws UpfProgrammableException {
- var pdrBuilder = PacketDetectionRule.builder();
- Pair<PiCriterion, PiTableAction> matchActionPair = FabricUpfTranslatorUtil.fabricEntryToPiPair(entry);
- PiCriterion match = matchActionPair.getLeft();
- PiAction action = (PiAction) matchActionPair.getRight();
-
- // Grab keys and parameters that are present for all PDRs
- int globalFarId = FabricUpfTranslatorUtil.getParamInt(action, FAR_ID);
- UpfRuleIdentifier farId = fabricUpfStore.localFarIdOf(globalFarId);
- if (farId == null) {
- throw new UpfProgrammableException(String.format("Unable to find local far id of %s", globalFarId));
- }
-
- pdrBuilder.withCounterId(FabricUpfTranslatorUtil.getParamInt(action, CTR_ID))
- .withLocalFarId(farId.getSessionLocalId())
- .withSessionId(farId.getPfcpSessionId());
-
- PiActionId actionId = action.id();
- if (actionId.equals(FABRIC_INGRESS_SPGW_LOAD_PDR_QOS)) {
- pdrBuilder.withQfi(FabricUpfTranslatorUtil.getParamByte(action, QFI));
- if (FabricUpfTranslatorUtil.getParamByte(action, NEEDS_QFI_PUSH) == TRUE) {
- pdrBuilder.withQfiPush();
- }
- }
-
- if (FabricUpfTranslatorUtil.fieldIsPresent(match, HDR_TEID)) {
- // F-TEID is only present for GTP-matching PDRs
- ImmutableByteSequence teid = FabricUpfTranslatorUtil.getFieldValue(match, HDR_TEID);
- Ip4Address tunnelDst = FabricUpfTranslatorUtil.getFieldAddress(match, HDR_TUNNEL_IPV4_DST);
- pdrBuilder.withTeid(teid)
- .withTunnelDst(tunnelDst);
- if (FabricUpfTranslatorUtil.fieldIsPresent(match, HDR_HAS_QFI) &&
- FabricUpfTranslatorUtil.getFieldByte(match, HDR_HAS_QFI) == TRUE) {
- pdrBuilder.withQfi(FabricUpfTranslatorUtil.getFieldByte(match, HDR_QFI));
- pdrBuilder.withQfiMatch();
- }
- } else if (FabricUpfTranslatorUtil.fieldIsPresent(match, HDR_UE_ADDR)) {
- // And UE address is only present for non-GTP-matching PDRs
- pdrBuilder.withUeAddr(FabricUpfTranslatorUtil.getFieldAddress(match, HDR_UE_ADDR));
- } else {
- throw new UpfProgrammableException("Read malformed PDR from dataplane!:" + entry);
- }
- return pdrBuilder.build();
- }
-
- /**
- * Translate a fabric.p4 FAR table entry to a ForwardActionRule instance for easier handling.
- *
- * @param entry the fabric.p4 entry to translate
- * @return the corresponding ForwardingActionRule
- * @throws UpfProgrammableException if the entry cannot be translated
- */
- public ForwardingActionRule fabricEntryToFar(FlowRule entry)
- throws UpfProgrammableException {
- var farBuilder = ForwardingActionRule.builder();
- Pair<PiCriterion, PiTableAction> matchActionPair = FabricUpfTranslatorUtil.fabricEntryToPiPair(entry);
- PiCriterion match = matchActionPair.getLeft();
- PiAction action = (PiAction) matchActionPair.getRight();
-
- int globalFarId = FabricUpfTranslatorUtil.getFieldInt(match, HDR_FAR_ID);
- UpfRuleIdentifier farId = fabricUpfStore.localFarIdOf(globalFarId);
- if (farId == null) {
- throw new UpfProgrammableException(String.format("Unable to find local far id of %s", globalFarId));
- }
-
- boolean dropFlag = FabricUpfTranslatorUtil.getParamInt(action, DROP) > 0;
- boolean notifyFlag = FabricUpfTranslatorUtil.getParamInt(action, NOTIFY_CP) > 0;
-
- // Match keys
- farBuilder.withSessionId(farId.getPfcpSessionId())
- .setFarId(farId.getSessionLocalId());
-
- // Parameters common to all types of FARs
- farBuilder.setDropFlag(dropFlag)
- .setNotifyFlag(notifyFlag);
-
- PiActionId actionId = action.id();
-
- if (actionId.equals(FABRIC_INGRESS_SPGW_LOAD_TUNNEL_FAR)
- || actionId.equals(FABRIC_INGRESS_SPGW_LOAD_DBUF_FAR)) {
- // Grab parameters specific to encapsulating FARs if they're present
- Ip4Address tunnelSrc = FabricUpfTranslatorUtil.getParamAddress(action, TUNNEL_SRC_ADDR);
- Ip4Address tunnelDst = FabricUpfTranslatorUtil.getParamAddress(action, TUNNEL_DST_ADDR);
- ImmutableByteSequence teid = FabricUpfTranslatorUtil.getParamValue(action, TEID);
- short tunnelSrcPort = (short) FabricUpfTranslatorUtil.getParamInt(action, TUNNEL_SRC_PORT);
-
- farBuilder.setBufferFlag(actionId.equals(FABRIC_INGRESS_SPGW_LOAD_DBUF_FAR));
-
- farBuilder.setTunnel(
- GtpTunnel.builder()
- .setSrc(tunnelSrc)
- .setDst(tunnelDst)
- .setTeid(teid)
- .setSrcPort(tunnelSrcPort)
- .build());
- }
- return farBuilder.build();
- }
-
- /**
- * Translate a fabric.p4 interface table entry to a UpfInterface instance for easier handling.
- *
- * @param entry the fabric.p4 entry to translate
- * @return the corresponding UpfInterface
- * @throws UpfProgrammableException if the entry cannot be translated
- */
- public UpfInterface fabricEntryToInterface(FlowRule entry)
- throws UpfProgrammableException {
- Pair<PiCriterion, PiTableAction> matchActionPair = FabricUpfTranslatorUtil.fabricEntryToPiPair(entry);
- PiCriterion match = matchActionPair.getLeft();
- PiAction action = (PiAction) matchActionPair.getRight();
-
- var ifaceBuilder = UpfInterface.builder()
- .setPrefix(FabricUpfTranslatorUtil.getFieldPrefix(match, HDR_IPV4_DST_ADDR));
-
- int interfaceType = FabricUpfTranslatorUtil.getParamInt(action, SRC_IFACE);
- if (interfaceType == INTERFACE_ACCESS) {
- ifaceBuilder.setAccess();
- } else if (interfaceType == INTERFACE_CORE) {
- ifaceBuilder.setCore();
- } else if (interfaceType == INTERFACE_DBUF) {
- ifaceBuilder.setDbufReceiver();
- }
- return ifaceBuilder.build();
- }
-
- /**
- * Translate a ForwardingActionRule to a FlowRule to be inserted into the fabric.p4 pipeline.
- * A side effect of calling this method is the FAR object's globalFarId is assigned if it was not already.
- *
- * @param far The FAR to be translated
- * @param deviceId the ID of the device the FlowRule should be installed on
- * @param appId the ID of the application that will insert the FlowRule
- * @param priority the FlowRule's priority
- * @return the FAR translated to a FlowRule
- * @throws UpfProgrammableException if the FAR to be translated is malformed
- */
- public FlowRule farToFabricEntry(ForwardingActionRule far, DeviceId deviceId, ApplicationId appId, int priority)
- throws UpfProgrammableException {
- PiAction action;
- if (!far.encaps()) {
- action = PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_NORMAL_FAR)
- .withParameters(Arrays.asList(
- new PiActionParam(DROP, far.drops() ? 1 : 0),
- new PiActionParam(NOTIFY_CP, far.notifies() ? 1 : 0)
- ))
- .build();
-
- } else {
- if (far.tunnelSrc() == null || far.tunnelDst() == null
- || far.teid() == null || far.tunnel().srcPort() == null) {
- throw new UpfProgrammableException(
- "Not all action parameters present when translating " +
- "intermediate encapsulating/buffering FAR to physical FAR!");
- }
- // TODO: copy tunnel destination port from logical switch write requests, instead of hardcoding 2152
- PiActionId actionId = far.buffers() ? FABRIC_INGRESS_SPGW_LOAD_DBUF_FAR :
- FABRIC_INGRESS_SPGW_LOAD_TUNNEL_FAR;
- action = PiAction.builder()
- .withId(actionId)
- .withParameters(Arrays.asList(
- new PiActionParam(DROP, far.drops() ? 1 : 0),
- new PiActionParam(NOTIFY_CP, far.notifies() ? 1 : 0),
- new PiActionParam(TEID, far.teid()),
- new PiActionParam(TUNNEL_SRC_ADDR, far.tunnelSrc().toInt()),
- new PiActionParam(TUNNEL_DST_ADDR, far.tunnelDst().toInt()),
- new PiActionParam(TUNNEL_SRC_PORT, far.tunnel().srcPort())
- ))
- .build();
- }
- PiCriterion match = PiCriterion.builder()
- .matchExact(HDR_FAR_ID, fabricUpfStore.globalFarIdOf(far.sessionId(), far.farId()))
- .build();
- return DefaultFlowRule.builder()
- .forDevice(deviceId).fromApp(appId).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_FARS)
- .withSelector(DefaultTrafficSelector.builder().matchPi(match).build())
- .withTreatment(DefaultTrafficTreatment.builder().piTableAction(action).build())
- .withPriority(priority)
- .build();
- }
-
- /**
- * Translate a PacketDetectionRule to a FlowRule to be inserted into the fabric.p4 pipeline.
- * A side effect of calling this method is the PDR object's globalFarId is assigned if it was not already.
- *
- * @param pdr The PDR to be translated
- * @param deviceId the ID of the device the FlowRule should be installed on
- * @param appId the ID of the application that will insert the FlowRule
- * @param priority the FlowRule's priority
- * @return the FAR translated to a FlowRule
- * @throws UpfProgrammableException if the PDR to be translated is malformed
- */
- public FlowRule pdrToFabricEntry(PacketDetectionRule pdr, DeviceId deviceId, ApplicationId appId, int priority)
- throws UpfProgrammableException {
- final PiCriterion match;
- final PiTableId tableId;
- final PiAction action;
-
- final PiCriterion.Builder matchBuilder = PiCriterion.builder();
-
- PiAction.Builder actionBuilder = PiAction.builder()
- .withParameters(Arrays.asList(
- new PiActionParam(CTR_ID, pdr.counterId()),
- new PiActionParam(FAR_ID, fabricUpfStore.globalFarIdOf(pdr.sessionId(), pdr.farId())),
- new PiActionParam(NEEDS_GTPU_DECAP, pdr.matchesEncapped() ?
- TRUE : FALSE),
- new PiActionParam(TC, DEFAULT_TC)
- ));
- PiActionId actionId = FABRIC_INGRESS_SPGW_LOAD_PDR;
- if (pdr.matchesEncapped()) {
- tableId = FABRIC_INGRESS_SPGW_UPLINK_PDRS;
- matchBuilder.matchExact(HDR_TEID, pdr.teid().asArray())
- .matchExact(HDR_TUNNEL_IPV4_DST, pdr.tunnelDest().toInt());
- if (pdr.matchQfi()) {
- matchBuilder.matchExact(HDR_HAS_QFI, TRUE)
- .matchExact(HDR_QFI, pdr.qfi());
- } else {
- matchBuilder.matchExact(HDR_HAS_QFI, FALSE)
- .matchExact(HDR_QFI, DEFAULT_QFI);
- if (pdr.hasQfi()) {
- actionId = FABRIC_INGRESS_SPGW_LOAD_PDR_QOS;
- actionBuilder.withParameter(new PiActionParam(QFI, pdr.qfi()))
- .withParameter(new PiActionParam(NEEDS_QFI_PUSH, FALSE));
- }
- }
- } else if (pdr.matchesUnencapped()) {
- tableId = FABRIC_INGRESS_SPGW_DOWNLINK_PDRS;
- matchBuilder.matchExact(HDR_UE_ADDR, pdr.ueAddress().toInt());
- if (pdr.hasQfi()) {
- actionBuilder.withParameter(new PiActionParam(QFI, pdr.qfi()))
- .withParameter(new PiActionParam(NEEDS_QFI_PUSH, pdr.pushQfi() ? TRUE : FALSE));
- actionId = FABRIC_INGRESS_SPGW_LOAD_PDR_QOS;
- }
- } else {
- throw new UpfProgrammableException("Flexible PDRs not yet supported! Cannot translate " + pdr);
- }
- match = matchBuilder.build();
- action = actionBuilder.withId(actionId)
- .build();
- return DefaultFlowRule.builder()
- .forDevice(deviceId).fromApp(appId).makePermanent()
- .forTable(tableId)
- .withSelector(DefaultTrafficSelector.builder().matchPi(match).build())
- .withTreatment(DefaultTrafficTreatment.builder().piTableAction(action).build())
- .withPriority(priority)
- .build();
- }
-
- /**
- * Translate a UpfInterface to a FlowRule to be inserted into the fabric.p4 pipeline.
- *
- * @param upfInterface The interface to be translated
- * @param deviceId the ID of the device the FlowRule should be installed on
- * @param appId the ID of the application that will insert the FlowRule
- * @param priority the FlowRule's priority
- * @return the UPF interface translated to a FlowRule
- * @throws UpfProgrammableException if the interface cannot be translated
- */
- public FlowRule interfaceToFabricEntry(UpfInterface upfInterface, DeviceId deviceId,
- ApplicationId appId, int priority)
- throws UpfProgrammableException {
- int interfaceTypeInt;
- int gtpuValidity;
- if (upfInterface.isDbufReceiver()) {
- interfaceTypeInt = INTERFACE_DBUF;
- gtpuValidity = 1;
- } else if (upfInterface.isAccess()) {
- interfaceTypeInt = INTERFACE_ACCESS;
- gtpuValidity = 1;
- } else {
- interfaceTypeInt = INTERFACE_CORE;
- gtpuValidity = 0;
- }
-
- PiCriterion match = PiCriterion.builder()
- .matchLpm(HDR_IPV4_DST_ADDR,
- upfInterface.prefix().address().toInt(),
- upfInterface.prefix().prefixLength())
- .matchExact(HDR_GTPU_IS_VALID, gtpuValidity)
- .build();
- PiAction action = PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_IFACE)
- .withParameter(new PiActionParam(SRC_IFACE, interfaceTypeInt))
- .withParameter(new PiActionParam(SLICE_ID, DEFAULT_SLICE_ID))
- .build();
- return DefaultFlowRule.builder()
- .forDevice(deviceId).fromApp(appId).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_INTERFACES)
- .withSelector(DefaultTrafficSelector.builder().matchPi(match).build())
- .withTreatment(DefaultTrafficTreatment.builder().piTableAction(action).build())
- .withPriority(priority)
- .build();
- }
-}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslatorUtil.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslatorUtil.java
deleted file mode 100644
index cfbf95e..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslatorUtil.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.apache.commons.lang3.tuple.Pair;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.util.ImmutableByteSequence;
-import org.onosproject.net.behaviour.upf.UpfProgrammableException;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.PiCriterion;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.PiInstruction;
-import org.onosproject.net.pi.model.PiActionParamId;
-import org.onosproject.net.pi.model.PiMatchFieldId;
-import org.onosproject.net.pi.model.PiMatchType;
-import org.onosproject.net.pi.runtime.PiAction;
-import org.onosproject.net.pi.runtime.PiActionParam;
-import org.onosproject.net.pi.runtime.PiExactFieldMatch;
-import org.onosproject.net.pi.runtime.PiFieldMatch;
-import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
-import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
-import org.onosproject.net.pi.runtime.PiTableAction;
-import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
-
-import java.util.Optional;
-
-/**
- * Utility class for manipulation of FlowRules and PiTableEntry objects specific to fabric-tna.
- */
-final class FabricUpfTranslatorUtil {
-
- private FabricUpfTranslatorUtil() {
- }
-
- static ImmutableByteSequence getFieldValue(PiFieldMatch field, PiMatchFieldId fieldId)
- throws UpfProgrammableException {
- if (field == null) {
- throw new UpfProgrammableException(
- String.format("Unable to find field %s where expected!", fieldId.toString()));
- }
- if (field.type() == PiMatchType.EXACT) {
- return ((PiExactFieldMatch) field).value();
- } else if (field.type() == PiMatchType.LPM) {
- return ((PiLpmFieldMatch) field).value();
- } else if (field.type() == PiMatchType.TERNARY) {
- return ((PiTernaryFieldMatch) field).value();
- } else if (field.type() == PiMatchType.RANGE) {
- return ((PiRangeFieldMatch) field).lowValue();
- } else {
- throw new UpfProgrammableException(
- String.format("Field %s has unknown match type: %s", fieldId.toString(), field.type().toString()));
- }
- }
-
- static ImmutableByteSequence getFieldValue(PiCriterion criterion, PiMatchFieldId fieldId)
- throws UpfProgrammableException {
- return getFieldValue(criterion.fieldMatch(fieldId).orElse(null), fieldId);
- }
-
- static boolean fieldIsPresent(PiCriterion criterion, PiMatchFieldId fieldId) {
- return criterion.fieldMatch(fieldId).isPresent();
- }
-
- static ImmutableByteSequence getParamValue(PiAction action, PiActionParamId paramId)
- throws UpfProgrammableException {
-
- for (PiActionParam param : action.parameters()) {
- if (param.id().equals(paramId)) {
- return param.value();
- }
- }
- throw new UpfProgrammableException(
- String.format("Unable to find parameter %s where expected!", paramId.toString()));
- }
-
- static int getFieldInt(PiCriterion criterion, PiMatchFieldId fieldId)
- throws UpfProgrammableException {
- return byteSeqToInt(getFieldValue(criterion, fieldId));
- }
-
- static byte getFieldByte(PiCriterion criterion, PiMatchFieldId fieldId)
- throws UpfProgrammableException {
- return byteSeqToByte(getFieldValue(criterion, fieldId));
- }
-
- static int getParamInt(PiAction action, PiActionParamId paramId)
- throws UpfProgrammableException {
- return byteSeqToInt(getParamValue(action, paramId));
- }
-
- static byte getParamByte(PiAction action, PiActionParamId paramId)
- throws UpfProgrammableException {
- return byteSeqToByte(getParamValue(action, paramId));
- }
-
- static Ip4Address getParamAddress(PiAction action, PiActionParamId paramId)
- throws UpfProgrammableException {
- return Ip4Address.valueOf(getParamValue(action, paramId).asArray());
- }
-
- static Ip4Prefix getFieldPrefix(PiCriterion criterion, PiMatchFieldId fieldId) {
- Optional<PiFieldMatch> optField = criterion.fieldMatch(fieldId);
- if (optField.isEmpty()) {
- return null;
- }
- PiLpmFieldMatch field = (PiLpmFieldMatch) optField.get();
- Ip4Address address = Ip4Address.valueOf(field.value().asArray());
- return Ip4Prefix.valueOf(address, field.prefixLength());
- }
-
- static Ip4Address getFieldAddress(PiCriterion criterion, PiMatchFieldId fieldId)
- throws UpfProgrammableException {
- return Ip4Address.valueOf(getFieldValue(criterion, fieldId).asArray());
- }
-
- static int byteSeqToInt(ImmutableByteSequence sequence) {
- try {
- return sequence.fit(32).asReadOnlyBuffer().getInt();
- } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
- throw new IllegalArgumentException("Attempted to convert a >4 byte wide sequence to an integer!");
- }
- }
-
- static byte byteSeqToByte(ImmutableByteSequence sequence) {
- try {
- return sequence.fit(8).asReadOnlyBuffer().get();
- } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
- throw new IllegalArgumentException("Attempted to convert a >1 byte wide sequence to a byte!");
- }
- }
-
- static Pair<PiCriterion, PiTableAction> fabricEntryToPiPair(FlowRule entry) {
- PiCriterion match = (PiCriterion) entry.selector().getCriterion(Criterion.Type.PROTOCOL_INDEPENDENT);
- PiTableAction action = null;
- for (Instruction instruction : entry.treatment().allInstructions()) {
- if (instruction.type() == Instruction.Type.PROTOCOL_INDEPENDENT) {
- PiInstruction piInstruction = (PiInstruction) instruction;
- action = piInstruction.action();
- break;
- }
- }
- return Pair.of(match, action);
- }
-}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/UpfRuleIdentifier.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/UpfRuleIdentifier.java
deleted file mode 100644
index 5b6c6b6..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/UpfRuleIdentifier.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.onlab.util.ImmutableByteSequence;
-
-import java.util.Objects;
-
-/**
- * Wrapper for identifying information of FARs and PDRs.
- */
-public final class UpfRuleIdentifier {
- private final int sessionlocalId;
- private final ImmutableByteSequence pfcpSessionId;
-
- /**
- * A PDR or FAR can be globally uniquely identified by the combination of the ID of the PFCP session that
- * produced it, and the ID that the rule was assigned in that PFCP session.
- *
- * @param pfcpSessionId The PFCP session that produced the rule ID
- * @param sessionlocalId The rule ID
- */
- public UpfRuleIdentifier(ImmutableByteSequence pfcpSessionId, int sessionlocalId) {
- this.pfcpSessionId = pfcpSessionId;
- this.sessionlocalId = sessionlocalId;
- }
-
- /**
- * Create an instance of this class from the given PFCP session ID and the session-local Rule ID.
- *
- * @param pfcpSessionId PFCP session ID of the rule to identify
- * @param sessionlocalId session-local Rule ID of the rule to identify
- * @return a new rule identifier
- */
- public static UpfRuleIdentifier of(ImmutableByteSequence pfcpSessionId, int sessionlocalId) {
- return new UpfRuleIdentifier(pfcpSessionId, sessionlocalId);
- }
-
- /**
- * Get the PFCP session-local rule ID.
- *
- * @return session-local rule ID
- */
- public int getSessionLocalId() {
- return sessionlocalId;
- }
-
- /**
- * Get the PFCP session ID.
- *
- * @return PFCP session ID
- */
- public ImmutableByteSequence getPfcpSessionId() {
- return pfcpSessionId;
- }
-
- @Override
- public String toString() {
- return "RuleIdentifier{" +
- "sessionlocalId=" + sessionlocalId +
- ", pfcpSessionId=" + pfcpSessionId +
- '}';
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- UpfRuleIdentifier that = (UpfRuleIdentifier) obj;
- return (this.sessionlocalId == that.sessionlocalId) && (this.pfcpSessionId.equals(that.pfcpSessionId));
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(this.sessionlocalId, this.pfcpSessionId);
- }
-}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/package-info.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/package-info.java
deleted file mode 100644
index 42591786..0000000
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2021-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.
- */
-
-/**
- * UPF programmable behaviour implementation for fabric-v1model.
- */
-package org.onosproject.pipelines.fabric.impl.behaviour.upf;
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfProgrammableTest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfProgrammableTest.java
deleted file mode 100644
index 50fd8bc..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfProgrammableTest.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import com.google.common.collect.ImmutableList;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.junit.TestUtils;
-import org.onlab.util.HexString;
-import org.onosproject.TestApplicationId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.upf.ForwardingActionRule;
-import org.onosproject.net.behaviour.upf.PacketDetectionRule;
-import org.onosproject.net.behaviour.upf.PdrStats;
-import org.onosproject.net.behaviour.upf.UpfInterface;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.config.basics.BasicDeviceConfig;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.DriverData;
-import org.onosproject.net.driver.DriverHandler;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.packet.PacketService;
-import org.onosproject.net.pi.model.PiCounterModel;
-import org.onosproject.net.pi.model.PiTableModel;
-import org.onosproject.net.pi.service.PiPipeconfService;
-import org.onosproject.net.pi.service.PiTranslationService;
-import org.onosproject.p4runtime.api.P4RuntimeController;
-import org.onosproject.pipelines.fabric.impl.FabricPipeconfLoader;
-import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
-
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.ConcurrentMap;
-
-import static junit.framework.TestCase.assertNotNull;
-import static junit.framework.TestCase.assertTrue;
-import static org.easymock.EasyMock.anyString;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_EGRESS_SPGW_PDR_COUNTER;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_DOWNLINK_PDRS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_FARS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_PDR_COUNTER;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_UPLINK_PDRS;
-
-public class FabricUpfProgrammableTest {
-
- private static final ApplicationId APP_ID =
- TestApplicationId.create(FabricPipeconfLoader.PIPELINE_APP_NAME);
-
- private final DistributedFabricUpfStore upfStore = TestDistributedFabricUpfStore.build();
- private MockPacketService packetService;
- private FabricUpfProgrammable upfProgrammable;
-
- // Bytes of a random but valid Ethernet frame.
- private static final byte[] ETH_FRAME_BYTES = HexString.fromHexString(
- "00060708090a0001020304058100000a08004500006a000100004011f92ec0a80001c0a8000204d2005" +
- "00056a8d5000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" +
- "2122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454" +
- "64748494a4b4c4d", "");
- private static final TrafficTreatment TABLE_OUTPUT_TREATMENT = DefaultTrafficTreatment.builder()
- .setOutput(PortNumber.TABLE)
- .build();
-
- private static final List<PiTableModel> TABLE_MODELS = ImmutableList.of(
- new MockTableModel(FABRIC_INGRESS_SPGW_UPLINK_PDRS,
- TestUpfConstants.PHYSICAL_MAX_PDRS / 2),
- new MockTableModel(FABRIC_INGRESS_SPGW_DOWNLINK_PDRS,
- TestUpfConstants.PHYSICAL_MAX_PDRS / 2),
- new MockTableModel(FABRIC_INGRESS_SPGW_FARS,
- TestUpfConstants.PHYSICAL_MAX_FARS)
- );
- private static final List<PiCounterModel> COUNTER_MODELS = ImmutableList.of(
- new MockCounterModel(FABRIC_INGRESS_SPGW_PDR_COUNTER,
- TestUpfConstants.PHYSICAL_COUNTER_SIZE),
- new MockCounterModel(FABRIC_EGRESS_SPGW_PDR_COUNTER,
- TestUpfConstants.PHYSICAL_COUNTER_SIZE)
- );
-
- @Before
- public void setUp() throws Exception {
- FabricCapabilities capabilities = createMock(FabricCapabilities.class);
- expect(capabilities.supportUpf()).andReturn(true).anyTimes();
- replay(capabilities);
-
- // Services mock
- packetService = new MockPacketService();
- CoreService coreService = createMock(CoreService.class);
- NetworkConfigService netcfgService = createMock(NetworkConfigService.class);
- DeviceService deviceService = createMock(DeviceService.class);
- PiTranslationService piTranslationService = createMock(PiTranslationService.class);
- expect(coreService.getAppId(anyString())).andReturn(APP_ID).anyTimes();
- expect(netcfgService.getConfig(TestUpfConstants.DEVICE_ID, BasicDeviceConfig.class))
- .andReturn(TestUpfUtils.getBasicConfig(TestUpfConstants.DEVICE_ID, "/basic.json"))
- .anyTimes();
- replay(coreService, netcfgService);
-
- // Mock driverData to get the right device ID
- DriverData driverData = createMock(DriverData.class);
- expect(driverData.deviceId()).andReturn(TestUpfConstants.DEVICE_ID).anyTimes();
- replay(driverData);
-
- // Mock DriverHandler to get all the required mocked services
- DriverHandler driverHandler = createMock(DriverHandler.class);
- expect(driverHandler.get(FlowRuleService.class)).andReturn(new MockFlowRuleService()).anyTimes();
- expect(driverHandler.get(PacketService.class)).andReturn(packetService).anyTimes();
- expect(driverHandler.get(FabricUpfStore.class)).andReturn(upfStore).anyTimes();
- expect(driverHandler.get(NetworkConfigService.class)).andReturn(netcfgService).anyTimes();
- expect(driverHandler.get(CoreService.class)).andReturn(coreService).anyTimes();
- expect(driverHandler.get(DeviceService.class)).andReturn(deviceService).anyTimes();
- expect(driverHandler.get(PiTranslationService.class)).andReturn(piTranslationService).anyTimes();
- expect(driverHandler.get(PiPipeconfService.class))
- .andReturn(new MockPiPipeconfService(TABLE_MODELS, COUNTER_MODELS))
- .anyTimes();
- expect(driverHandler.get(P4RuntimeController.class))
- .andReturn(new MockP4RuntimeController(TestUpfConstants.DEVICE_ID,
- TestUpfConstants.COUNTER_PKTS,
- TestUpfConstants.COUNTER_BYTES,
- TestUpfConstants.PHYSICAL_COUNTER_SIZE))
- .anyTimes();
- expect(driverHandler.data()).andReturn(driverData).anyTimes();
- replay(driverHandler);
-
- upfProgrammable = new FabricUpfProgrammable();
- TestUtils.setField(upfProgrammable, "handler", driverHandler);
- TestUtils.setField(upfProgrammable, "data", driverData);
- ConcurrentMap<DeviceId, URI> channelUris = TestUtils.getField(upfProgrammable, "CHANNEL_URIS");
- channelUris.put(TestUpfConstants.DEVICE_ID, new URI("grpc://localhost:1234?device_id=1"));
- }
-
- @Test
- public void testUplinkPdr() throws Exception {
- assertTrue(upfProgrammable.getPdrs().isEmpty());
- PacketDetectionRule expectedPdr = TestUpfConstants.UPLINK_PDR;
- upfProgrammable.addPdr(expectedPdr);
- Collection<PacketDetectionRule> installedPdrs = upfProgrammable.getPdrs();
- assertThat(installedPdrs.size(), equalTo(1));
- for (var readPdr : installedPdrs) {
- assertThat(readPdr, equalTo(expectedPdr));
- }
- upfProgrammable.removePdr(expectedPdr.withoutActionParams());
- assertTrue(upfProgrammable.getPdrs().isEmpty());
- }
-
- @Test
- public void testDownlinkPdr() throws Exception {
- assertTrue(upfProgrammable.getPdrs().isEmpty());
- PacketDetectionRule expectedPdr = TestUpfConstants.DOWNLINK_PDR;
- upfProgrammable.addPdr(expectedPdr);
- Collection<PacketDetectionRule> installedPdrs = upfProgrammable.getPdrs();
- assertThat(installedPdrs.size(), equalTo(1));
- for (var readPdr : installedPdrs) {
- assertThat(readPdr, equalTo(expectedPdr));
- }
- upfProgrammable.removePdr(expectedPdr.withoutActionParams());
- assertTrue(upfProgrammable.getPdrs().isEmpty());
- }
-
- @Test
- public void testUplinkFar() throws Exception {
- assertTrue(upfProgrammable.getFars().isEmpty());
- ForwardingActionRule expectedFar = TestUpfConstants.UPLINK_FAR;
- upfProgrammable.addFar(expectedFar);
- Collection<ForwardingActionRule> installedFars = upfProgrammable.getFars();
- assertThat(installedFars.size(), equalTo(1));
- for (var readFar : installedFars) {
- assertThat(readFar, equalTo(expectedFar));
- }
- upfProgrammable.removeFar(expectedFar.withoutActionParams());
- assertTrue(upfProgrammable.getFars().isEmpty());
- }
-
- @Test
- public void testDownlinkFar() throws Exception {
- assertTrue(upfProgrammable.getFars().isEmpty());
- ForwardingActionRule expectedFar = TestUpfConstants.DOWNLINK_FAR;
- upfProgrammable.addFar(expectedFar);
- Collection<ForwardingActionRule> installedFars = upfProgrammable.getFars();
- assertThat(installedFars.size(), equalTo(1));
- for (var readFar : installedFars) {
- assertThat(readFar, equalTo(expectedFar));
- }
- upfProgrammable.removeFar(expectedFar.withoutActionParams());
- assertTrue(upfProgrammable.getFars().isEmpty());
- }
-
- @Test
- public void testUplinkInterface() throws Exception {
- assertTrue(upfProgrammable.getInterfaces().isEmpty());
- UpfInterface expectedInterface = TestUpfConstants.UPLINK_INTERFACE;
- upfProgrammable.addInterface(expectedInterface);
- Collection<UpfInterface> installedInterfaces = upfProgrammable.getInterfaces();
- assertThat(installedInterfaces.size(), equalTo(1));
- for (var readInterface : installedInterfaces) {
- assertThat(readInterface, equalTo(expectedInterface));
- }
- upfProgrammable.removeInterface(expectedInterface);
- assertTrue(upfProgrammable.getInterfaces().isEmpty());
- }
-
- @Test
- public void testDownlinkInterface() throws Exception {
- assertTrue(upfProgrammable.getInterfaces().isEmpty());
- UpfInterface expectedInterface = TestUpfConstants.DOWNLINK_INTERFACE;
- upfProgrammable.addInterface(expectedInterface);
- Collection<UpfInterface> installedInterfaces = upfProgrammable.getInterfaces();
- assertThat(installedInterfaces.size(), equalTo(1));
- for (var readInterface : installedInterfaces) {
- assertThat(readInterface, equalTo(expectedInterface));
- }
- upfProgrammable.removeInterface(expectedInterface);
- assertTrue(upfProgrammable.getInterfaces().isEmpty());
- }
-
- @Test
- public void testClearInterfaces() throws Exception {
- assertTrue(upfProgrammable.getInterfaces().isEmpty());
- upfProgrammable.addInterface(TestUpfConstants.UPLINK_INTERFACE);
- upfProgrammable.addInterface(TestUpfConstants.DOWNLINK_INTERFACE);
- assertThat(upfProgrammable.getInterfaces().size(), equalTo(2));
- upfProgrammable.clearInterfaces();
- assertTrue(upfProgrammable.getInterfaces().isEmpty());
- }
-
- @Test
- public void testReadAllCounters() {
- Collection<PdrStats> allStats = upfProgrammable.readAllCounters(-1);
- assertThat(allStats.size(), equalTo(TestUpfConstants.PHYSICAL_COUNTER_SIZE));
- for (PdrStats stat : allStats) {
- assertThat(stat.getIngressBytes(), equalTo(TestUpfConstants.COUNTER_BYTES));
- assertThat(stat.getEgressBytes(), equalTo(TestUpfConstants.COUNTER_BYTES));
- assertThat(stat.getIngressPkts(), equalTo(TestUpfConstants.COUNTER_PKTS));
- assertThat(stat.getEgressPkts(), equalTo(TestUpfConstants.COUNTER_PKTS));
- }
- }
-
- @Test
- public void testReadAllCountersLimitedCounters() {
- Collection<PdrStats> allStats = upfProgrammable.readAllCounters(10);
- assertThat(allStats.size(), equalTo(10));
- }
-
- @Test
- public void testReadAllCountersPhysicalLimit() {
- Collection<PdrStats> allStats = upfProgrammable.readAllCounters(1024);
- assertThat(allStats.size(), equalTo(TestUpfConstants.PHYSICAL_COUNTER_SIZE));
- }
-
- @Test
- public void testSendPacketOut() {
- upfProgrammable.sendPacketOut(ByteBuffer.wrap(ETH_FRAME_BYTES));
- var emittedPkt = packetService.emittedPackets.poll();
- assertNotNull(emittedPkt);
- assertThat(emittedPkt.data().array(), equalTo(ETH_FRAME_BYTES));
- assertThat(emittedPkt.treatment(), equalTo(TABLE_OUTPUT_TREATMENT));
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslatorTest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslatorTest.java
deleted file mode 100644
index a07826d..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/FabricUpfTranslatorTest.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.junit.Test;
-import org.onosproject.net.behaviour.upf.ForwardingActionRule;
-import org.onosproject.net.behaviour.upf.PacketDetectionRule;
-import org.onosproject.net.behaviour.upf.UpfInterface;
-import org.onosproject.net.behaviour.upf.UpfProgrammableException;
-import org.onosproject.net.flow.FlowRule;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-
-public class FabricUpfTranslatorTest {
-
- private final FabricUpfTranslator upfTranslator = new FabricUpfTranslator(TestDistributedFabricUpfStore.build());
-
- @Test
- public void fabricEntryToUplinkPdrTest() {
- fabricToPdrUplink(TestUpfConstants.UPLINK_PDR, TestUpfConstants.FABRIC_UPLINK_PDR);
- }
-
- @Test
- public void fabricEntryToUplinkQosPdrTest() {
- fabricToPdrUplink(TestUpfConstants.UPLINK_QOS_PDR, TestUpfConstants.FABRIC_UPLINK_QOS_PDR);
- fabricToPdrUplink(TestUpfConstants.UPLINK_QOS_4G_PDR, TestUpfConstants.FABRIC_UPLINK_QOS_4G_PDR);
- }
-
- private void fabricToPdrUplink(PacketDetectionRule expected, FlowRule fabricFlow) {
- PacketDetectionRule translatedPdr;
- try {
- translatedPdr = upfTranslator.fabricEntryToPdr(fabricFlow);
- } catch (UpfProgrammableException e) {
- assertThat("Fabric uplink PDR should translate to abstract PDR without error.", false);
- return;
- }
- assertThat("Translated PDR should be uplink.", translatedPdr.matchesEncapped());
- assertThat(translatedPdr, equalTo(expected));
- }
-
- @Test
- public void fabricEntryToDownlinkPdrTest() {
- fabricToPdrDownlink(TestUpfConstants.DOWNLINK_PDR, TestUpfConstants.FABRIC_DOWNLINK_PDR);
- }
-
- @Test
- public void fabricEntryToDownlinkQosPdrTest() {
- fabricToPdrDownlink(TestUpfConstants.DOWNLINK_QOS_PDR, TestUpfConstants.FABRIC_DOWNLINK_QOS_PDR);
- fabricToPdrDownlink(TestUpfConstants.DOWNLINK_QOS_4G_PDR, TestUpfConstants.FABRIC_DOWNLINK_QOS_4G_PDR);
- }
-
- private void fabricToPdrDownlink(PacketDetectionRule expected, FlowRule fabricFlow) {
- PacketDetectionRule translatedPdr;
- try {
- translatedPdr = upfTranslator.fabricEntryToPdr(fabricFlow);
- } catch (UpfProgrammableException e) {
- assertThat("Fabric downlink PDR should translate to abstract PDR without error.", false);
- return;
- }
-
- assertThat("Translated PDR should be downlink.", translatedPdr.matchesUnencapped());
- assertThat(translatedPdr, equalTo(expected));
- }
-
- @Test
- public void fabricEntryToUplinkFarTest() {
- ForwardingActionRule translatedFar;
- ForwardingActionRule expectedFar = TestUpfConstants.UPLINK_FAR;
- try {
- translatedFar = upfTranslator.fabricEntryToFar(TestUpfConstants.FABRIC_UPLINK_FAR);
- } catch (UpfProgrammableException e) {
- assertThat("Fabric uplink FAR should correctly translate to abstract FAR without error",
- false);
- return;
- }
- assertThat("Translated FAR should be uplink.", translatedFar.forwards());
- assertThat(translatedFar, equalTo(expectedFar));
- }
-
- @Test
- public void fabricEntryToDownlinkFarTest() {
- ForwardingActionRule translatedFar;
- ForwardingActionRule expectedFar = TestUpfConstants.DOWNLINK_FAR;
- try {
- translatedFar = upfTranslator.fabricEntryToFar(TestUpfConstants.FABRIC_DOWNLINK_FAR);
- } catch (UpfProgrammableException e) {
- assertThat("Fabric downlink FAR should correctly translate to abstract FAR without error",
- false);
- return;
- }
- assertThat("Translated FAR should be downlink.", translatedFar.encaps());
- assertThat(translatedFar, equalTo(expectedFar));
- }
-
- @Test
- public void fabricEntryToUplinkInterfaceTest() {
- UpfInterface translatedInterface;
- UpfInterface expectedInterface = TestUpfConstants.UPLINK_INTERFACE;
- try {
- translatedInterface = upfTranslator.fabricEntryToInterface(TestUpfConstants.FABRIC_UPLINK_INTERFACE);
- } catch (UpfProgrammableException e) {
- assertThat("Fabric uplink interface should correctly translate to abstract interface without error",
- false);
- return;
- }
- assertThat("Translated interface should be uplink.", translatedInterface.isAccess());
- assertThat(translatedInterface, equalTo(expectedInterface));
- }
-
- @Test
- public void fabricEntryToDownlinkInterfaceTest() {
- UpfInterface translatedInterface;
- UpfInterface expectedInterface = TestUpfConstants.DOWNLINK_INTERFACE;
- try {
- translatedInterface = upfTranslator.fabricEntryToInterface(TestUpfConstants.FABRIC_DOWNLINK_INTERFACE);
- } catch (UpfProgrammableException e) {
- assertThat("Fabric downlink interface should correctly translate to abstract interface without error",
- false);
- return;
- }
- assertThat("Translated interface should be downlink.", translatedInterface.isCore());
- assertThat(translatedInterface, equalTo(expectedInterface));
- }
-
- @Test
- public void uplinkInterfaceToFabricEntryTest() {
- FlowRule translatedRule;
- FlowRule expectedRule = TestUpfConstants.FABRIC_UPLINK_INTERFACE;
- try {
- translatedRule = upfTranslator.interfaceToFabricEntry(TestUpfConstants.UPLINK_INTERFACE,
- TestUpfConstants.DEVICE_ID,
- TestUpfConstants.APP_ID,
- TestUpfConstants.DEFAULT_PRIORITY);
- } catch (UpfProgrammableException e) {
- assertThat("Abstract uplink interface should correctly translate to Fabric interface without error",
- false);
- return;
- }
- assertThat(translatedRule, equalTo(expectedRule));
- }
-
- @Test
- public void downlinkInterfaceToFabricEntryTest() {
- FlowRule translatedRule;
- FlowRule expectedRule = TestUpfConstants.FABRIC_DOWNLINK_INTERFACE;
- try {
- translatedRule = upfTranslator.interfaceToFabricEntry(TestUpfConstants.DOWNLINK_INTERFACE,
- TestUpfConstants.DEVICE_ID,
- TestUpfConstants.APP_ID,
- TestUpfConstants.DEFAULT_PRIORITY);
- } catch (UpfProgrammableException e) {
- assertThat("Abstract downlink interface should correctly translate to Fabric interface without error",
- false);
- return;
- }
- assertThat(translatedRule, equalTo(expectedRule));
- }
-
- @Test
- public void downlinkPdrToFabricEntryTest() {
- pdrToFabricDownlink(TestUpfConstants.FABRIC_DOWNLINK_PDR, TestUpfConstants.DOWNLINK_PDR);
- }
-
- @Test
- public void downlinkPdrToFabricQosEntryTest() {
- pdrToFabricDownlink(TestUpfConstants.FABRIC_DOWNLINK_QOS_PDR, TestUpfConstants.DOWNLINK_QOS_PDR);
- pdrToFabricDownlink(TestUpfConstants.FABRIC_DOWNLINK_QOS_4G_PDR, TestUpfConstants.DOWNLINK_QOS_4G_PDR);
- }
-
- private void pdrToFabricDownlink(FlowRule expected, PacketDetectionRule pdr) {
- FlowRule translatedRule;
- try {
- translatedRule = upfTranslator.pdrToFabricEntry(pdr,
- TestUpfConstants.DEVICE_ID,
- TestUpfConstants.APP_ID,
- TestUpfConstants.DEFAULT_PRIORITY);
- } catch (UpfProgrammableException e) {
- assertThat("Abstract downlink PDR should correctly translate to Fabric PDR without error",
- false);
- return;
- }
- assertThat(translatedRule, equalTo(expected));
- }
-
- @Test
- public void uplinkFarToFabricEntryTest() {
- FlowRule translatedRule;
- FlowRule expectedRule = TestUpfConstants.FABRIC_UPLINK_FAR;
- try {
- translatedRule = upfTranslator.farToFabricEntry(TestUpfConstants.UPLINK_FAR,
- TestUpfConstants.DEVICE_ID,
- TestUpfConstants.APP_ID,
- TestUpfConstants.DEFAULT_PRIORITY);
- } catch (UpfProgrammableException e) {
- assertThat("Abstract uplink FAR should correctly translate to Fabric FAR without error",
- false);
- return;
- }
- assertThat(translatedRule, equalTo(expectedRule));
- }
-
- @Test
- public void uplinkPdrToFabricEntryTest() {
- pdrToFabricUplink(TestUpfConstants.FABRIC_UPLINK_PDR, TestUpfConstants.UPLINK_PDR);
- }
-
- @Test
- public void uplinkQosPdrToFabricEntryTest() {
- pdrToFabricUplink(TestUpfConstants.FABRIC_UPLINK_QOS_PDR, TestUpfConstants.UPLINK_QOS_PDR);
- pdrToFabricUplink(TestUpfConstants.FABRIC_UPLINK_QOS_4G_PDR, TestUpfConstants.UPLINK_QOS_4G_PDR);
- }
-
- private void pdrToFabricUplink(FlowRule expected, PacketDetectionRule pdr) {
- FlowRule translatedRule;
- try {
- translatedRule = upfTranslator.pdrToFabricEntry(pdr,
- TestUpfConstants.DEVICE_ID,
- TestUpfConstants.APP_ID,
- TestUpfConstants.DEFAULT_PRIORITY);
- } catch (UpfProgrammableException e) {
- assertThat("Abstract uplink PDR should correctly translate to Fabric PDR without error",
- false);
- return;
- }
- assertThat(translatedRule, equalTo(expected));
- }
-
- @Test
- public void downlinkFarToFabricEntryTest() {
- FlowRule translatedRule;
- FlowRule expectedRule = TestUpfConstants.FABRIC_DOWNLINK_FAR;
- try {
- translatedRule = upfTranslator.farToFabricEntry(TestUpfConstants.DOWNLINK_FAR,
- TestUpfConstants.DEVICE_ID,
- TestUpfConstants.APP_ID,
- TestUpfConstants.DEFAULT_PRIORITY);
- } catch (UpfProgrammableException e) {
- assertThat("Abstract downlink FAR should correctly translate to Fabric FAR without error",
- false);
- return;
- }
- assertThat(translatedRule, equalTo(expectedRule));
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockCounterModel.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockCounterModel.java
deleted file mode 100644
index dcf667b..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockCounterModel.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.onosproject.net.pi.model.PiCounterId;
-import org.onosproject.net.pi.model.PiCounterModel;
-import org.onosproject.net.pi.model.PiCounterType;
-import org.onosproject.net.pi.model.PiTableId;
-
-public class MockCounterModel implements PiCounterModel {
- PiCounterId id;
- int size;
-
- public MockCounterModel(PiCounterId id, int size) {
- this.id = id;
- this.size = size;
- }
-
- @Override
- public PiCounterId id() {
- return this.id;
- }
-
- @Override
- public PiCounterType counterType() {
- return null;
- }
-
- @Override
- public Unit unit() {
- return null;
- }
-
- @Override
- public PiTableId table() {
- return null;
- }
-
- @Override
- public long size() {
- return this.size;
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockFlowRuleService.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockFlowRuleService.java
deleted file mode 100644
index 055a4be..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockFlowRuleService.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import com.google.common.collect.Sets;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.flow.DefaultFlowEntry;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleOperations;
-import org.onosproject.net.flow.FlowRuleServiceAdapter;
-
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.stream.Collectors;
-
-public class MockFlowRuleService extends FlowRuleServiceAdapter {
-
- final Set<FlowRule> flows = Sets.newHashSet();
- boolean success;
-
- int errorFlow = -1;
-
- public void setErrorFlow(int errorFlow) {
- this.errorFlow = errorFlow;
- }
-
- public void setFuture(boolean success) {
- this.success = success;
- }
-
- @Override
- public void apply(FlowRuleOperations ops) {
- AtomicBoolean thisSuccess = new AtomicBoolean(success);
- ops.stages().forEach(stage -> stage.forEach(flow -> {
- if (errorFlow == flow.rule().id().value()) {
- thisSuccess.set(false);
- } else {
- switch (flow.type()) {
- case ADD:
- case MODIFY: //TODO is this the right behavior for modify?
- flows.add(flow.rule());
- break;
- case REMOVE:
- flows.remove(flow.rule());
- break;
- default:
- break;
- }
- }
- }));
- if (thisSuccess.get()) {
- ops.callback().onSuccess(ops);
- } else {
- ops.callback().onError(ops);
- }
- }
-
- @Override
- public int getFlowRuleCount() {
- return flows.size();
- }
-
- @Override
- public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
- return flows.stream()
- .filter(flow -> flow.deviceId().equals(deviceId))
- .map(DefaultFlowEntry::new)
- .collect(Collectors.toList());
- }
-
- @Override
- public void applyFlowRules(FlowRule... flowRules) {
- for (FlowRule flow : flowRules) {
- flows.add(flow);
- }
- }
-
- @Override
- public void removeFlowRules(FlowRule... flowRules) {
- for (FlowRule flow : flowRules) {
- flows.remove(flow);
- }
- }
-
- @Override
- public Iterable<FlowRule> getFlowRulesByGroupId(ApplicationId appId, short groupId) {
- return flows.stream()
- .filter(flow -> flow.appId() == appId.id() && flow.groupId().id() == groupId)
- .collect(Collectors.toList());
- }
-
- @Override
- public Iterable<FlowEntry> getFlowEntriesById(ApplicationId id) {
- return flows.stream()
- .filter(flow -> flow.appId() == id.id())
- .map(DefaultFlowEntry::new)
- .collect(Collectors.toList());
- }
-}
-
-
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockP4RuntimeController.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockP4RuntimeController.java
deleted file mode 100644
index 5fc42d5..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockP4RuntimeController.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import io.grpc.ManagedChannel;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.device.DeviceAgentListener;
-import org.onosproject.net.pi.model.PiPipeconf;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.p4runtime.api.P4RuntimeClient;
-import org.onosproject.p4runtime.api.P4RuntimeController;
-import org.onosproject.p4runtime.api.P4RuntimeEventListener;
-
-import static org.easymock.EasyMock.anyLong;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
-/**
- * Currently only used to get mock clients that mock counter read requests.
- */
-public class MockP4RuntimeController implements P4RuntimeController {
-
- private final P4RuntimeClient mockP4rtClient;
-
- /**
- * Used to mock counter read requests.
- *
- * @param deviceId The ID of the device
- * @param packets Packets counter value
- * @param bytes Bytes counter value
- * @param counterSize The size of the counter array
- */
- public MockP4RuntimeController(DeviceId deviceId, long packets, long bytes, int counterSize) {
- mockP4rtClient = createMock(P4RuntimeClient.class);
- expect(mockP4rtClient.read(anyLong(), anyObject(PiPipeconf.class)))
- .andReturn(new MockReadRequest(deviceId, packets, bytes, counterSize))
- .anyTimes();
- replay(mockP4rtClient);
- }
-
- @Override
- public P4RuntimeClient get(DeviceId deviceId) {
- return mockP4rtClient;
- }
-
- @Override
- public void addListener(P4RuntimeEventListener listener) {
-
- }
-
- @Override
- public void removeListener(P4RuntimeEventListener listener) {
-
- }
-
- @Override
- public boolean create(DeviceId deviceId, ManagedChannel channel) {
- return false;
- }
-
- @Override
- public void remove(DeviceId deviceId) {
-
- }
-
- @Override
- public void addDeviceAgentListener(DeviceId deviceId, ProviderId providerId,
- DeviceAgentListener listener) {
-
- }
-
- @Override
- public void removeDeviceAgentListener(DeviceId deviceId,
- ProviderId providerId) {
-
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPacketService.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPacketService.java
deleted file mode 100644
index 8dc0928..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPacketService.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import com.google.common.collect.Queues;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.packet.OutboundPacket;
-import org.onosproject.net.packet.PacketPriority;
-import org.onosproject.net.packet.PacketProcessor;
-import org.onosproject.net.packet.PacketProcessorEntry;
-import org.onosproject.net.packet.PacketRequest;
-import org.onosproject.net.packet.PacketService;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.Queue;
-
-public class MockPacketService implements PacketService {
-
- Queue<OutboundPacket> emittedPackets = Queues.newArrayDeque();
-
- @Override
- public void addProcessor(PacketProcessor processor, int priority) {
-
- }
-
- @Override
- public void removeProcessor(PacketProcessor processor) {
-
- }
-
- @Override
- public List<PacketProcessorEntry> getProcessors() {
- return null;
- }
-
- @Override
- public void requestPackets(TrafficSelector selector, PacketPriority priority, ApplicationId appId) {
-
- }
-
- @Override
- public void requestPackets(TrafficSelector selector, PacketPriority priority,
- ApplicationId appId, Optional<DeviceId> deviceId) {
-
- }
-
- @Override
- public void cancelPackets(TrafficSelector selector, PacketPriority priority, ApplicationId appId) {
-
- }
-
- @Override
- public void cancelPackets(TrafficSelector selector, PacketPriority priority,
- ApplicationId appId, Optional<DeviceId> deviceId) {
-
- }
-
- @Override
- public List<PacketRequest> getRequests() {
- return null;
- }
-
- @Override
- public void emit(OutboundPacket packet) {
- emittedPackets.add(packet);
- }
-}
-
-
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipeconfService.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipeconfService.java
deleted file mode 100644
index 20c7839..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipeconfService.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.pi.model.PiCounterModel;
-import org.onosproject.net.pi.model.PiPipeconf;
-import org.onosproject.net.pi.model.PiPipeconfId;
-import org.onosproject.net.pi.model.PiTableModel;
-import org.onosproject.net.pi.service.PiPipeconfListener;
-import org.onosproject.net.pi.service.PiPipeconfService;
-
-import java.util.Collection;
-import java.util.Optional;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
-public class MockPiPipeconfService implements PiPipeconfService {
-
- private final PiPipeconf mockPiPipeconf;
-
- public MockPiPipeconfService(Collection<PiTableModel> tables,
- Collection<PiCounterModel> counters) {
- mockPiPipeconf = createMock(PiPipeconf.class);
- expect(mockPiPipeconf.pipelineModel())
- .andReturn(new MockPiPipelineModel(tables, counters))
- .anyTimes();
- replay(mockPiPipeconf);
- }
-
- @Override
- public Optional<PiPipeconf> getPipeconf(PiPipeconfId id) {
- return Optional.of(mockPiPipeconf);
- }
-
- @Override
- public Optional<PiPipeconf> getPipeconf(DeviceId deviceId) {
- return Optional.of(mockPiPipeconf);
- }
-
- @Override
- public void register(PiPipeconf pipeconf) throws IllegalStateException {
-
- }
-
- @Override
- public void unregister(PiPipeconfId pipeconfId) throws IllegalStateException {
-
- }
-
- @Override
- public Iterable<PiPipeconf> getPipeconfs() {
- return null;
- }
-
- @Override
- public void bindToDevice(PiPipeconfId pipeconfId, DeviceId deviceId) {
-
- }
-
- @Override
- public String getMergedDriver(DeviceId deviceId, PiPipeconfId pipeconfId) {
- return null;
- }
-
- @Override
- public Optional<PiPipeconfId> ofDevice(DeviceId deviceId) {
- return Optional.empty();
- }
-
- @Override
- public void addListener(PiPipeconfListener listener) {
-
- }
-
- @Override
- public void removeListener(PiPipeconfListener listener) {
-
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipelineModel.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipelineModel.java
deleted file mode 100644
index 2560346..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipelineModel.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import com.google.common.collect.Maps;
-import org.onosproject.net.pi.model.PiActionProfileId;
-import org.onosproject.net.pi.model.PiActionProfileModel;
-import org.onosproject.net.pi.model.PiCounterId;
-import org.onosproject.net.pi.model.PiCounterModel;
-import org.onosproject.net.pi.model.PiMeterId;
-import org.onosproject.net.pi.model.PiMeterModel;
-import org.onosproject.net.pi.model.PiPacketOperationModel;
-import org.onosproject.net.pi.model.PiPacketOperationType;
-import org.onosproject.net.pi.model.PiPipelineModel;
-import org.onosproject.net.pi.model.PiRegisterId;
-import org.onosproject.net.pi.model.PiRegisterModel;
-import org.onosproject.net.pi.model.PiTableId;
-import org.onosproject.net.pi.model.PiTableModel;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-
-public class MockPiPipelineModel implements PiPipelineModel {
-
- private final Map<PiTableId, PiTableModel> tableMap = Maps.newHashMap();
-
- private final List<PiCounterModel> counters;
-
- public MockPiPipelineModel(Collection<PiTableModel> tables, Collection<PiCounterModel> counters) {
- tables.forEach(tableModel -> tableMap.put(tableModel.id(), tableModel));
- this.counters = List.copyOf(counters);
- }
-
- @Override
- public Optional<String> architecture() {
- return Optional.empty();
- }
-
- @Override
- public Optional<PiTableModel> table(PiTableId tableId) {
- return Optional.ofNullable(tableMap.getOrDefault(tableId, null));
- }
-
- @Override
- public Collection<PiTableModel> tables() {
- return tableMap.values();
- }
-
- @Override
- public Optional<PiCounterModel> counter(PiCounterId counterId) {
- return Optional.empty();
- }
-
- @Override
- public Collection<PiCounterModel> counters() {
- return counters;
- }
-
- @Override
- public Optional<PiMeterModel> meter(PiMeterId meterId) {
- return Optional.empty();
- }
-
- @Override
- public Collection<PiMeterModel> meters() {
- return null;
- }
-
- @Override
- public Optional<PiRegisterModel> register(PiRegisterId registerId) {
- return Optional.empty();
- }
-
- @Override
- public Collection<PiRegisterModel> registers() {
- return null;
- }
-
- @Override
- public Optional<PiActionProfileModel> actionProfiles(PiActionProfileId actionProfileId) {
- return Optional.empty();
- }
-
- @Override
- public Collection<PiActionProfileModel> actionProfiles() {
- return null;
- }
-
- @Override
- public Optional<PiPacketOperationModel> packetOperationModel(PiPacketOperationType type) {
- return Optional.empty();
- }
-
-
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockReadRequest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockReadRequest.java
deleted file mode 100644
index 32be8d9..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockReadRequest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.pi.model.PiActionProfileId;
-import org.onosproject.net.pi.model.PiCounterId;
-import org.onosproject.net.pi.model.PiMeterId;
-import org.onosproject.net.pi.model.PiTableId;
-import org.onosproject.net.pi.runtime.PiCounterCellHandle;
-import org.onosproject.net.pi.runtime.PiCounterCellId;
-import org.onosproject.net.pi.runtime.PiHandle;
-import org.onosproject.p4runtime.api.P4RuntimeReadClient;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.stream.LongStream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * For faking reads to a p4runtime client. Currently only used for testing
- * UP4-specific counter reads, because all other P4 entities that UP4 reads can
- * be read via other ONOS services.
- */
-public class MockReadRequest implements P4RuntimeReadClient.ReadRequest {
- List<PiHandle> handles;
- DeviceId deviceId;
- long packets;
- long bytes;
- int counterSize;
-
- public MockReadRequest(DeviceId deviceId, long packets, long bytes, int counterSize) {
- this.handles = new ArrayList<>();
- this.deviceId = deviceId;
- this.packets = packets;
- this.bytes = bytes;
- this.counterSize = counterSize;
- }
-
- @Override
- public CompletableFuture<P4RuntimeReadClient.ReadResponse> submit() {
- return CompletableFuture.completedFuture(
- new MockReadResponse(this.handles, this.packets, this.bytes));
- }
-
- @Override
- public P4RuntimeReadClient.ReadResponse submitSync() {
- return new MockReadResponse(this.handles, this.packets, this.bytes);
- }
-
-
- @Override
- public P4RuntimeReadClient.ReadRequest handle(PiHandle handle) {
- this.handles.add(handle);
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest handles(Iterable<? extends PiHandle> handles) {
- checkNotNull(handles);
- handles.forEach(this::handle);
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest tableEntries(PiTableId tableId) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest tableEntries(Iterable<PiTableId> tableIds) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest defaultTableEntry(PiTableId tableId) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest defaultTableEntry(Iterable<PiTableId> tableIds) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest allTableEntries() {
- return null;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest allDefaultTableEntries() {
- return null;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest actionProfileGroups(PiActionProfileId actionProfileId) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest actionProfileGroups(Iterable<PiActionProfileId> actionProfileIds) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest actionProfileMembers(PiActionProfileId actionProfileId) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest actionProfileMembers(Iterable<PiActionProfileId> actionProfileIds) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest counterCells(PiCounterId counterId) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest counterCells(Iterable<PiCounterId> counterIds) {
- counterIds.forEach(counterId -> {
- LongStream.range(0, this.counterSize)
- .forEach(index -> {
- PiCounterCellId cellId =
- PiCounterCellId.ofIndirect(counterId, index);
- PiCounterCellHandle handle =
- PiCounterCellHandle.of(this.deviceId, cellId);
- this.handle(handle);
- });
- });
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest directCounterCells(PiTableId tableId) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest directCounterCells(Iterable<PiTableId> tableIds) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest meterCells(PiMeterId meterId) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest meterCells(Iterable<PiMeterId> meterIds) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest directMeterCells(PiTableId tableId) {
- return this;
- }
-
- @Override
- public P4RuntimeReadClient.ReadRequest directMeterCells(Iterable<PiTableId> tableIds) {
- return this;
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockReadResponse.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockReadResponse.java
deleted file mode 100644
index 2dbc11f..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockReadResponse.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.onosproject.net.pi.runtime.PiCounterCell;
-import org.onosproject.net.pi.runtime.PiCounterCellData;
-import org.onosproject.net.pi.runtime.PiCounterCellHandle;
-import org.onosproject.net.pi.runtime.PiEntity;
-import org.onosproject.net.pi.runtime.PiEntityType;
-import org.onosproject.net.pi.runtime.PiHandle;
-import org.onosproject.p4runtime.api.P4RuntimeReadClient;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * For faking reads to a p4runtime client. Currently only used for testing
- * UP4-specific counter reads, because all other P4 entities that UP4 reads can
- * be read via other ONOS services.
- */
-public class MockReadResponse implements P4RuntimeReadClient.ReadResponse {
- List<PiEntity> entities;
- long packets;
- long bytes;
-
- public MockReadResponse(Iterable<? extends PiHandle> handles, long packets, long bytes) {
- this.entities = new ArrayList<>();
- this.packets = packets;
- this.bytes = bytes;
- checkNotNull(handles);
- handles.forEach(this::handle);
- }
-
- @Override
- public boolean isSuccess() {
- return true;
- }
-
- public MockReadResponse handle(PiHandle handle) {
- if (handle.entityType().equals(PiEntityType.COUNTER_CELL)) {
- PiCounterCellHandle counterHandle = (PiCounterCellHandle) handle;
- PiCounterCellData data =
- new PiCounterCellData(this.packets, this.bytes);
- PiEntity entity = new PiCounterCell(counterHandle.cellId(), data);
- this.entities.add(entity);
- }
- // Only handles counter cell so far
-
- return this;
- }
-
- @Override
- public Collection<PiEntity> all() {
- return this.entities;
- }
-
- @Override
- public <E extends PiEntity> Collection<E> all(Class<E> clazz) {
- List<E> results = new ArrayList<>();
- this.entities.forEach(ent -> {
- if (ent.getClass().equals(clazz)) {
- results.add(clazz.cast(ent));
- }
- });
- return results;
- }
-
- @Override
- public String explanation() {
- return null;
- }
-
- @Override
- public Throwable throwable() {
- return null;
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockTableModel.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockTableModel.java
deleted file mode 100644
index b8b9d26..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockTableModel.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.onosproject.net.pi.model.PiActionId;
-import org.onosproject.net.pi.model.PiActionModel;
-import org.onosproject.net.pi.model.PiActionProfileModel;
-import org.onosproject.net.pi.model.PiCounterModel;
-import org.onosproject.net.pi.model.PiMatchFieldId;
-import org.onosproject.net.pi.model.PiMatchFieldModel;
-import org.onosproject.net.pi.model.PiMeterModel;
-import org.onosproject.net.pi.model.PiTableId;
-import org.onosproject.net.pi.model.PiTableModel;
-import org.onosproject.net.pi.model.PiTableType;
-
-import java.util.Collection;
-import java.util.Optional;
-
-public class MockTableModel implements PiTableModel {
- PiTableId id;
- int size;
-
- public MockTableModel(PiTableId id, int size) {
- this.id = id;
- this.size = size;
- }
-
- @Override
- public PiTableId id() {
- return this.id;
- }
-
- @Override
- public PiTableType tableType() {
- return null;
- }
-
- @Override
- public PiActionProfileModel actionProfile() {
- return null;
- }
-
- @Override
- public long maxSize() {
- return size;
- }
-
- @Override
- public Collection<PiCounterModel> counters() {
- return null;
- }
-
- @Override
- public Collection<PiMeterModel> meters() {
- return null;
- }
-
- @Override
- public boolean supportsAging() {
- return false;
- }
-
- @Override
- public Collection<PiMatchFieldModel> matchFields() {
- return null;
- }
-
- @Override
- public Collection<PiActionModel> actions() {
- return null;
- }
-
- @Override
- public Optional<PiActionModel> constDefaultAction() {
- return Optional.empty();
- }
-
- @Override
- public boolean isConstantTable() {
- return false;
- }
-
- @Override
- public boolean oneShotOnly() {
- return false;
- }
-
- @Override
- public Optional<PiActionModel> action(PiActionId actionId) {
- return Optional.empty();
- }
-
- @Override
- public Optional<PiMatchFieldModel> matchField(PiMatchFieldId matchFieldId) {
- return Optional.empty();
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestDistributedFabricUpfStore.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestDistributedFabricUpfStore.java
deleted file mode 100644
index 3bf3b26..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestDistributedFabricUpfStore.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import org.onosproject.store.service.TestEventuallyConsistentMap;
-import org.onosproject.store.service.WallClockTimestamp;
-
-import static org.onosproject.pipelines.fabric.impl.behaviour.upf.DistributedFabricUpfStore.FAR_ID_MAP_NAME;
-import static org.onosproject.pipelines.fabric.impl.behaviour.upf.DistributedFabricUpfStore.SERIALIZER;
-
-
-public final class TestDistributedFabricUpfStore {
-
- private TestDistributedFabricUpfStore() {
- }
-
- public static DistributedFabricUpfStore build() {
- var store = new DistributedFabricUpfStore();
- TestEventuallyConsistentMap.Builder<Integer, UpfRuleIdentifier> reverseFarIdMapBuilder =
- TestEventuallyConsistentMap.builder();
- reverseFarIdMapBuilder.withName(FAR_ID_MAP_NAME)
- .withTimestampProvider((k, v) -> new WallClockTimestamp())
- .withSerializer(SERIALIZER.build());
- store.reverseFarIdMap = reverseFarIdMapBuilder.build();
-
- store.activate();
-
- // Init with some translation state.
- store.reverseFarIdMap.put(TestUpfConstants.UPLINK_PHYSICAL_FAR_ID,
- new UpfRuleIdentifier(TestUpfConstants.SESSION_ID, TestUpfConstants.UPLINK_FAR_ID));
- store.reverseFarIdMap.put(TestUpfConstants.DOWNLINK_PHYSICAL_FAR_ID,
- new UpfRuleIdentifier(TestUpfConstants.SESSION_ID, TestUpfConstants.DOWNLINK_FAR_ID));
-
- return store;
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestUpfConstants.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestUpfConstants.java
deleted file mode 100644
index 71c7212..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestUpfConstants.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import com.google.common.hash.Hashing;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.util.ImmutableByteSequence;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.DefaultApplicationId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.behaviour.upf.ForwardingActionRule;
-import org.onosproject.net.behaviour.upf.PacketDetectionRule;
-import org.onosproject.net.behaviour.upf.UpfInterface;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.criteria.PiCriterion;
-import org.onosproject.net.pi.runtime.PiAction;
-import org.onosproject.net.pi.runtime.PiActionParam;
-
-import java.util.Arrays;
-
-import static org.onosproject.pipelines.fabric.FabricConstants.CTR_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.DROP;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_DOWNLINK_PDRS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_FARS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_INTERFACES;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_IFACE;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_NORMAL_FAR;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_PDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_PDR_QOS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_LOAD_TUNNEL_FAR;
-import static org.onosproject.pipelines.fabric.FabricConstants.FABRIC_INGRESS_SPGW_UPLINK_PDRS;
-import static org.onosproject.pipelines.fabric.FabricConstants.FAR_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_FAR_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_GTPU_IS_VALID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_HAS_QFI;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_IPV4_DST_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_QFI;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_TEID;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_TUNNEL_IPV4_DST;
-import static org.onosproject.pipelines.fabric.FabricConstants.HDR_UE_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.NEEDS_GTPU_DECAP;
-import static org.onosproject.pipelines.fabric.FabricConstants.NEEDS_QFI_PUSH;
-import static org.onosproject.pipelines.fabric.FabricConstants.NOTIFY_CP;
-import static org.onosproject.pipelines.fabric.FabricConstants.QFI;
-import static org.onosproject.pipelines.fabric.FabricConstants.SLICE_ID;
-import static org.onosproject.pipelines.fabric.FabricConstants.SRC_IFACE;
-import static org.onosproject.pipelines.fabric.FabricConstants.TC;
-import static org.onosproject.pipelines.fabric.FabricConstants.TEID;
-import static org.onosproject.pipelines.fabric.FabricConstants.TUNNEL_DST_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.TUNNEL_SRC_ADDR;
-import static org.onosproject.pipelines.fabric.FabricConstants.TUNNEL_SRC_PORT;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_QFI;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_SLICE_ID;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_TC;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FALSE;
-import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.TRUE;
-import static org.onosproject.pipelines.fabric.impl.behaviour.upf.FabricUpfTranslator.INTERFACE_ACCESS;
-import static org.onosproject.pipelines.fabric.impl.behaviour.upf.FabricUpfTranslator.INTERFACE_CORE;
-
-
-public final class TestUpfConstants {
- public static final DeviceId DEVICE_ID = DeviceId.deviceId("CoolSwitch91");
- public static final ApplicationId APP_ID = new DefaultApplicationId(5000, "up4");
- public static final int DEFAULT_PRIORITY = 10;
- // SESSION_ID_BITWIDTH / 8 = 12
- public static final ImmutableByteSequence SESSION_ID = ImmutableByteSequence.ofOnes(12);
- public static final int UPLINK_COUNTER_CELL_ID = 1;
- public static final int DOWNLINK_COUNTER_CELL_ID = 2;
- public static final int PDR_ID = 0; // TODO: PDR ID currently not stored on writes, so all reads are 0
- public static final int UPLINK_FAR_ID = 1;
- public static final int UPLINK_PHYSICAL_FAR_ID = Hashing.murmur3_32()
- .newHasher()
- .putInt(UPLINK_FAR_ID)
- .putBytes(SESSION_ID.asArray())
- .hash()
- .asInt();
- public static final int DOWNLINK_FAR_ID = 2;
- public static final int DOWNLINK_PHYSICAL_FAR_ID = Hashing.murmur3_32()
- .newHasher()
- .putInt(DOWNLINK_FAR_ID)
- .putBytes(SESSION_ID.asArray())
- .hash()
- .asInt();
-
- public static final byte UPLINK_QFI = 1;
- public static final byte DOWNLINK_QFI = 5;
-
- public static final ImmutableByteSequence TEID_VALUE = ImmutableByteSequence.copyFrom(0xff);
- public static final Ip4Address UE_ADDR = Ip4Address.valueOf("17.0.0.1");
- public static final Ip4Address S1U_ADDR = Ip4Address.valueOf("192.168.0.1");
- public static final Ip4Address ENB_ADDR = Ip4Address.valueOf("192.168.0.2");
- public static final Ip4Prefix UE_POOL = Ip4Prefix.valueOf("17.0.0.0/16");
- // TODO: tunnel source port currently not stored on writes, so all reads are 0
- public static final short TUNNEL_SPORT = 2160;
- public static final int PHYSICAL_COUNTER_SIZE = 512;
- public static final int PHYSICAL_MAX_PDRS = 512;
- public static final int PHYSICAL_MAX_FARS = 512;
-
- public static final long COUNTER_BYTES = 12;
- public static final long COUNTER_PKTS = 15;
-
- public static final PacketDetectionRule UPLINK_PDR = PacketDetectionRule.builder()
- .withTunnelDst(S1U_ADDR)
- .withTeid(TEID_VALUE)
- .withLocalFarId(UPLINK_FAR_ID)
- .withSessionId(SESSION_ID)
- .withCounterId(UPLINK_COUNTER_CELL_ID)
- .build();
-
- public static final PacketDetectionRule DOWNLINK_PDR = PacketDetectionRule.builder()
- .withUeAddr(UE_ADDR)
- .withLocalFarId(DOWNLINK_FAR_ID)
- .withSessionId(SESSION_ID)
- .withCounterId(DOWNLINK_COUNTER_CELL_ID)
- .build();
-
- public static final PacketDetectionRule UPLINK_QOS_PDR = PacketDetectionRule.builder()
- .withTunnelDst(S1U_ADDR)
- .withTeid(TEID_VALUE)
- .withLocalFarId(UPLINK_FAR_ID)
- .withSessionId(SESSION_ID)
- .withCounterId(UPLINK_COUNTER_CELL_ID)
- .withQfi(UPLINK_QFI)
- .withQfiMatch()
- .build();
-
- public static final PacketDetectionRule UPLINK_QOS_4G_PDR = PacketDetectionRule.builder()
- .withTunnelDst(S1U_ADDR)
- .withTeid(TEID_VALUE)
- .withLocalFarId(UPLINK_FAR_ID)
- .withSessionId(SESSION_ID)
- .withCounterId(UPLINK_COUNTER_CELL_ID)
- .withQfi(UPLINK_QFI)
- .build();
-
- public static final PacketDetectionRule DOWNLINK_QOS_PDR = PacketDetectionRule.builder()
- .withUeAddr(UE_ADDR)
- .withLocalFarId(DOWNLINK_FAR_ID)
- .withSessionId(SESSION_ID)
- .withCounterId(DOWNLINK_COUNTER_CELL_ID)
- .withQfi(DOWNLINK_QFI)
- .withQfiPush()
- .build();
-
- public static final PacketDetectionRule DOWNLINK_QOS_4G_PDR = PacketDetectionRule.builder()
- .withUeAddr(UE_ADDR)
- .withLocalFarId(DOWNLINK_FAR_ID)
- .withSessionId(SESSION_ID)
- .withCounterId(DOWNLINK_COUNTER_CELL_ID)
- .withQfi(DOWNLINK_QFI)
- .build();
-
- public static final ForwardingActionRule UPLINK_FAR = ForwardingActionRule.builder()
- .setFarId(UPLINK_FAR_ID)
- .withSessionId(SESSION_ID).build();
-
- public static final ForwardingActionRule DOWNLINK_FAR = ForwardingActionRule.builder()
- .setFarId(DOWNLINK_FAR_ID)
- .withSessionId(SESSION_ID)
- .setTunnel(S1U_ADDR, ENB_ADDR, TEID_VALUE, TUNNEL_SPORT)
- .build();
-
- public static final UpfInterface UPLINK_INTERFACE = UpfInterface.createS1uFrom(S1U_ADDR);
-
- public static final UpfInterface DOWNLINK_INTERFACE = UpfInterface.createUePoolFrom(UE_POOL);
-
- public static final FlowRule FABRIC_UPLINK_QOS_PDR = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_UPLINK_PDRS)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchExact(HDR_TEID, TEID_VALUE.asArray())
- .matchExact(HDR_TUNNEL_IPV4_DST, S1U_ADDR.toInt())
- .matchExact(HDR_HAS_QFI, TRUE)
- .matchExact(HDR_QFI, UPLINK_QFI)
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_PDR)
- .withParameters(Arrays.asList(
- new PiActionParam(CTR_ID, UPLINK_COUNTER_CELL_ID),
- new PiActionParam(FAR_ID, UPLINK_PHYSICAL_FAR_ID),
- new PiActionParam(NEEDS_GTPU_DECAP, TRUE),
- new PiActionParam(TC, DEFAULT_TC)
- ))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_UPLINK_QOS_4G_PDR = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_UPLINK_PDRS)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchExact(HDR_TEID, TEID_VALUE.asArray())
- .matchExact(HDR_TUNNEL_IPV4_DST, S1U_ADDR.toInt())
- .matchExact(HDR_HAS_QFI, FALSE)
- .matchExact(HDR_QFI, DEFAULT_QFI)
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_PDR_QOS)
- .withParameters(Arrays.asList(
- new PiActionParam(CTR_ID, UPLINK_COUNTER_CELL_ID),
- new PiActionParam(FAR_ID, UPLINK_PHYSICAL_FAR_ID),
- new PiActionParam(NEEDS_GTPU_DECAP, TRUE),
- new PiActionParam(NEEDS_QFI_PUSH, FALSE),
- new PiActionParam(QFI,
- UPLINK_QFI),
- new PiActionParam(TC, DEFAULT_TC)
- ))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_DOWNLINK_QOS_PDR = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_DOWNLINK_PDRS)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchExact(HDR_UE_ADDR, UE_ADDR.toInt())
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_PDR_QOS)
- .withParameters(Arrays.asList(
- new PiActionParam(CTR_ID, DOWNLINK_COUNTER_CELL_ID),
- new PiActionParam(FAR_ID, DOWNLINK_PHYSICAL_FAR_ID),
- new PiActionParam(QFI, DOWNLINK_QFI),
- new PiActionParam(NEEDS_GTPU_DECAP, FALSE),
- new PiActionParam(NEEDS_QFI_PUSH, TRUE),
- new PiActionParam(TC, DEFAULT_TC)
- ))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_DOWNLINK_QOS_4G_PDR = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_DOWNLINK_PDRS)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchExact(HDR_UE_ADDR, UE_ADDR.toInt())
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_PDR_QOS)
- .withParameters(Arrays.asList(
- new PiActionParam(CTR_ID, DOWNLINK_COUNTER_CELL_ID),
- new PiActionParam(FAR_ID, DOWNLINK_PHYSICAL_FAR_ID),
- new PiActionParam(QFI, DOWNLINK_QFI),
- new PiActionParam(NEEDS_GTPU_DECAP, FALSE),
- new PiActionParam(NEEDS_QFI_PUSH, FALSE),
- new PiActionParam(TC, DEFAULT_TC)
- ))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_UPLINK_PDR = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_UPLINK_PDRS)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchExact(HDR_TEID, TEID_VALUE.asArray())
- .matchExact(HDR_TUNNEL_IPV4_DST, S1U_ADDR.toInt())
- .matchExact(HDR_HAS_QFI, FALSE)
- .matchExact(HDR_QFI, DEFAULT_QFI)
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_PDR)
- .withParameters(Arrays.asList(
- new PiActionParam(CTR_ID, UPLINK_COUNTER_CELL_ID),
- new PiActionParam(FAR_ID, UPLINK_PHYSICAL_FAR_ID),
- new PiActionParam(NEEDS_GTPU_DECAP, TRUE),
- new PiActionParam(TC, DEFAULT_TC)
- ))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_DOWNLINK_PDR = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_DOWNLINK_PDRS)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchExact(HDR_UE_ADDR, UE_ADDR.toInt())
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_PDR)
- .withParameters(Arrays.asList(
- new PiActionParam(CTR_ID, DOWNLINK_COUNTER_CELL_ID),
- new PiActionParam(FAR_ID, DOWNLINK_PHYSICAL_FAR_ID),
- new PiActionParam(NEEDS_GTPU_DECAP, FALSE),
- new PiActionParam(TC, DEFAULT_TC)
- ))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_UPLINK_FAR = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_FARS)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchExact(HDR_FAR_ID, UPLINK_PHYSICAL_FAR_ID)
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_NORMAL_FAR)
- .withParameters(Arrays.asList(
- new PiActionParam(DROP, 0),
- new PiActionParam(NOTIFY_CP, 0)
- ))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_DOWNLINK_FAR = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_FARS)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchExact(HDR_FAR_ID, DOWNLINK_PHYSICAL_FAR_ID)
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_TUNNEL_FAR)
- .withParameters(Arrays.asList(
- new PiActionParam(DROP, 0),
- new PiActionParam(NOTIFY_CP, 0),
- new PiActionParam(TEID, TEID_VALUE),
- new PiActionParam(TUNNEL_SRC_ADDR, S1U_ADDR.toInt()),
- new PiActionParam(TUNNEL_DST_ADDR, ENB_ADDR.toInt()),
- new PiActionParam(TUNNEL_SRC_PORT, TUNNEL_SPORT)
- ))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_UPLINK_INTERFACE = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_INTERFACES)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchLpm(HDR_IPV4_DST_ADDR,
- S1U_ADDR.toInt(),
- 32)
- .matchExact(HDR_GTPU_IS_VALID, 1)
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(
- PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_IFACE)
- .withParameter(new PiActionParam(SRC_IFACE, INTERFACE_ACCESS))
- .withParameter(new PiActionParam(SLICE_ID, DEFAULT_SLICE_ID))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- public static final FlowRule FABRIC_DOWNLINK_INTERFACE = DefaultFlowRule.builder()
- .forDevice(DEVICE_ID).fromApp(APP_ID).makePermanent()
- .forTable(FABRIC_INGRESS_SPGW_INTERFACES)
- .withSelector(DefaultTrafficSelector.builder()
- .matchPi(PiCriterion.builder()
- .matchLpm(HDR_IPV4_DST_ADDR,
- UE_POOL.address().toInt(),
- UE_POOL.prefixLength())
- .matchExact(HDR_GTPU_IS_VALID, 0)
- .build()).build())
- .withTreatment(DefaultTrafficTreatment.builder()
- .piTableAction(PiAction.builder()
- .withId(FABRIC_INGRESS_SPGW_LOAD_IFACE)
- .withParameter(new PiActionParam(SRC_IFACE, INTERFACE_CORE))
- .withParameter(new PiActionParam(SLICE_ID, DEFAULT_SLICE_ID))
- .build()).build())
- .withPriority(DEFAULT_PRIORITY)
- .build();
-
- /**
- * Hidden constructor for utility class.
- */
- private TestUpfConstants() {
- }
-}
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestUpfUtils.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestUpfUtils.java
deleted file mode 100644
index 6280f8e..0000000
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/TestUpfUtils.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.config.basics.BasicDeviceConfig;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public final class TestUpfUtils {
-
- private static final String BASIC_CONFIG_KEY = "basic";
-
- private TestUpfUtils() {
- // hide constructor
- }
-
- public static BasicDeviceConfig getBasicConfig(DeviceId deviceId, String fileName)
- throws IOException {
- BasicDeviceConfig basicCfg = new BasicDeviceConfig();
- InputStream jsonStream = TestUpfUtils.class.getResourceAsStream(fileName);
- ObjectMapper mapper = new ObjectMapper();
- JsonNode jsonNode = mapper.readTree(jsonStream);
- basicCfg.init(deviceId, BASIC_CONFIG_KEY, jsonNode, mapper, config -> {
- });
- return basicCfg;
- }
-}