blob: 22c25c0749daaaa8b4e33dd9a060954b1f603677 [file] [log] [blame]
tosinski36ba33a2021-11-22 16:53:00 +01001/*
2 * Copyright 2021-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.net.behaviour.upf;
18
19import com.google.common.annotations.Beta;
20import org.onlab.packet.Ip4Address;
21
22import java.util.Objects;
23
24import static com.google.common.base.Preconditions.checkNotNull;
25
26/**
27 * A structure representing the UE Termination in the downlink direction on the
28 * UPF-programmable device.
Daniele Moroa1c7ba42022-01-13 19:16:34 +010029 * Provide means to configure the traffic behavior (e.g. set Traffic Class, GTP TEID, or QFI).
tosinski36ba33a2021-11-22 16:53:00 +010030 */
31@Beta
32public final class UpfTerminationDownlink implements UpfEntity {
33 // Match Keys
34 private final Ip4Address ueSessionId; // UE Session ID, use UE IP address to uniquely identify a session.
Daniele Moroa1c7ba42022-01-13 19:16:34 +010035 private final byte applicationId; // Application ID, defaults to DEFAULT_APP_ID
tosinski36ba33a2021-11-22 16:53:00 +010036 // Action parameters
37 private final Integer ctrId; // Counter ID unique to this UPF Termination Rule
38 private final Byte trafficClass;
39 private final Integer teid; // Tunnel Endpoint Identifier
40 private final Byte qfi; // QoS Flow Identifier
Daniele Moro909b9582022-01-26 15:47:29 +010041 private final int appMeterIdx;
tosinski36ba33a2021-11-22 16:53:00 +010042 private final boolean dropping;
43
Daniele Moroa1c7ba42022-01-13 19:16:34 +010044 private UpfTerminationDownlink(Ip4Address ueSessionId, byte applicationId, Integer ctrId, Byte trafficClass,
Daniele Moro909b9582022-01-26 15:47:29 +010045 Integer teid, Byte qfi, int appMeterIdx, boolean dropping) {
tosinski36ba33a2021-11-22 16:53:00 +010046 this.ueSessionId = ueSessionId;
Daniele Moroa1c7ba42022-01-13 19:16:34 +010047 this.applicationId = applicationId;
tosinski36ba33a2021-11-22 16:53:00 +010048 this.ctrId = ctrId;
49 this.trafficClass = trafficClass;
50 this.teid = teid;
51 this.qfi = qfi;
Daniele Moro909b9582022-01-26 15:47:29 +010052 this.appMeterIdx = appMeterIdx;
tosinski36ba33a2021-11-22 16:53:00 +010053 this.dropping = dropping;
54 }
55
56 public static Builder builder() {
57 return new Builder();
58 }
59
60 @Override
61 public boolean equals(Object obj) {
62 if (obj == this) {
63 return true;
64 }
65 if (obj == null) {
66 return false;
67 }
68 if (getClass() != obj.getClass()) {
69 return false;
70 }
71 UpfTerminationDownlink that = (UpfTerminationDownlink) obj;
72
73 // Safe comparisons between potentially null objects
74 return this.dropping == that.dropping &&
75 Objects.equals(this.ueSessionId, that.ueSessionId) &&
Daniele Moroa1c7ba42022-01-13 19:16:34 +010076 Objects.equals(this.applicationId, that.applicationId) &&
tosinski36ba33a2021-11-22 16:53:00 +010077 Objects.equals(this.ctrId, that.ctrId) &&
78 Objects.equals(this.trafficClass, that.trafficClass) &&
79 Objects.equals(this.teid, that.teid) &&
Daniele Moro909b9582022-01-26 15:47:29 +010080 this.appMeterIdx == that.appMeterIdx &&
tosinski36ba33a2021-11-22 16:53:00 +010081 Objects.equals(this.qfi, that.qfi);
82 }
83
84 @Override
85 public int hashCode() {
Daniele Moro909b9582022-01-26 15:47:29 +010086 return Objects.hash(ueSessionId, applicationId, ctrId, trafficClass, teid, qfi, appMeterIdx, dropping);
tosinski36ba33a2021-11-22 16:53:00 +010087 }
88
89 /**
90 * Get UE Session ID associated with UPF Termination rule.
91 *
92 * @return UE Session ID
93 */
94 public Ip4Address ueSessionId() {
95 return ueSessionId;
96 }
97
98 /**
Daniele Moroa1c7ba42022-01-13 19:16:34 +010099 * Get the application ID associated with UPF Termination rule.
100 *
101 * @return the application ID
102 */
103 public byte applicationId() {
104 return applicationId;
105 }
106
107 /**
tosinski36ba33a2021-11-22 16:53:00 +0100108 * Get PDR Counter ID associated with UPF Termination rule.
109 *
110 * @return PDR counter cell ID
111 */
112 public Integer counterId() {
113 return ctrId;
114 }
115
116 /**
117 * Get Traffic Class set by this UPF Termination rule.
118 *
119 * @return Traffic Class
120 */
121 public Byte trafficClass() {
122 return trafficClass;
123 }
124
125 /**
126 * Get GTP TEID set by this UPF Termination rule.
127 *
128 * @return GTP tunnel ID
129 */
130 public Integer teid() {
131 return teid;
132 }
133
134 /**
135 * Get QoS Flow Identifier set by this UPF Termination rule.
136 *
137 * @return QoS Flow Identifier
138 */
139 public Byte qfi() {
140 return qfi;
141 }
142
143 /**
144 * True if this UPF Termination needs to drop traffic.
145 *
146 * @return true if the UPF Termination needs dropping.
147 */
148 public boolean needsDropping() {
149 return dropping;
150 }
151
Daniele Moro909b9582022-01-26 15:47:29 +0100152 /**
153 * Get the app meter index set by this UPF Termination rule.
154 *
155 * @return App meter index
156 */
157 public int appMeterIdx() {
158 return appMeterIdx;
159 }
160
tosinski36ba33a2021-11-22 16:53:00 +0100161 @Override
162 public UpfEntityType type() {
163 return UpfEntityType.TERMINATION_DOWNLINK;
164 }
165
166 @Override
167 public String toString() {
Daniele Morof3a5ab02022-01-26 16:47:08 +0100168 return "UpfTerminationDL(" + matchString() + " -> " + actionString() + ")";
tosinski36ba33a2021-11-22 16:53:00 +0100169 }
170
171 private String matchString() {
Daniele Moroa1c7ba42022-01-13 19:16:34 +0100172 return "Match(ue_addr=" + this.ueSessionId() + ", app_id=" + this.applicationId + ")";
tosinski36ba33a2021-11-22 16:53:00 +0100173 }
174
175 private String actionString() {
Daniele Moroa1c7ba42022-01-13 19:16:34 +0100176 String fwd = "FWD";
177 if (this.needsDropping()) {
178 fwd = "DROP";
179 }
Daniele Morof3a5ab02022-01-26 16:47:08 +0100180 return "Action(" + fwd +
181 ", teid=" + this.teid() +
182 ", ctr_id=" + this.counterId() +
183 ", qfi=" + this.qfi() +
184 ", tc=" + this.trafficClass() +
Daniele Moro909b9582022-01-26 15:47:29 +0100185 ", app_meter_idx=" + this.appMeterIdx() +
tosinski36ba33a2021-11-22 16:53:00 +0100186 ")";
187 }
188
189 public static class Builder {
190 private Ip4Address ueSessionId = null;
Daniele Moroa1c7ba42022-01-13 19:16:34 +0100191 private Byte applicationId = null;
tosinski36ba33a2021-11-22 16:53:00 +0100192 private Integer ctrId = null;
193 private Byte trafficClass = null;
194 private Integer teid = null;
195 private Byte qfi = null;
Daniele Moro909b9582022-01-26 15:47:29 +0100196 private int appMeterIdx = DEFAULT_APP_INDEX;
tosinski36ba33a2021-11-22 16:53:00 +0100197 private boolean drop = false;
198
199 public Builder() {
200
201 }
202
203 /**
204 * Set the ID of the UE session.
205 *
206 * @param ueSessionId UE session ID
207 * @return This builder object
208 */
209 public Builder withUeSessionId(Ip4Address ueSessionId) {
210 this.ueSessionId = ueSessionId;
211 return this;
212 }
213
214 /**
Daniele Moroa1c7ba42022-01-13 19:16:34 +0100215 * Set the ID of the application.
Daniele Moro909b9582022-01-26 15:47:29 +0100216 * If not set, default to {@link UpfEntity#DEFAULT_APP_ID}.
Daniele Moroa1c7ba42022-01-13 19:16:34 +0100217 *
218 * @param applicationId Application ID
219 * @return This builder object
220 */
221 public Builder withApplicationId(byte applicationId) {
222 this.applicationId = applicationId;
223 return this;
224 }
225
226 /**
tosinski36ba33a2021-11-22 16:53:00 +0100227 * Set the dataplane counter cell ID.
228 *
229 * @param ctrId PDR counter cell ID
230 * @return This builder object
231 */
232 public Builder withCounterId(int ctrId) {
233 this.ctrId = ctrId;
234 return this;
235 }
236
237 /**
238 * Set the Traffic Class.
239 *
240 * @param trafficClass Traffic Class
241 * @return This builder object
242 */
243 public Builder withTrafficClass(byte trafficClass) {
244 this.trafficClass = trafficClass;
245 return this;
246 }
247
248 /**
249 * Set the identifier of the unidirectional GTP tunnel that should be used for the UE Session.
250 *
251 * @param teid tunnel ID
252 * @return This builder object
253 */
254 public Builder withTeid(Integer teid) {
255 this.teid = teid;
256 return this;
257 }
258
259 /**
260 * Set the QoS Flow Identifier.
261 *
262 * @param qfi GTP Tunnel QFI
263 * @return This builder object
264 */
265 public Builder withQfi(byte qfi) {
266 this.qfi = qfi;
267 return this;
268 }
269
270 /**
271 * Sets whether to drop downlink UPF termination traffic or not.
272 *
Daniele Moroa1c7ba42022-01-13 19:16:34 +0100273 * @param drop True if request to drop, false otherwise
tosinski36ba33a2021-11-22 16:53:00 +0100274 * @return This builder object
275 */
276 public Builder needsDropping(boolean drop) {
277 this.drop = drop;
278 return this;
279 }
280
Daniele Moro909b9582022-01-26 15:47:29 +0100281 /**
282 * Sets the app meter index.
283 * If not set, default to {@link UpfEntity#DEFAULT_APP_INDEX}.
284 *
285 * @param appMeterIdx App meter index
286 * @return This builder object
287 */
288 public Builder withAppMeterIdx(int appMeterIdx) {
289 this.appMeterIdx = appMeterIdx;
290 return this;
291 }
292
tosinski36ba33a2021-11-22 16:53:00 +0100293 public UpfTerminationDownlink build() {
294 // Match fields must be provided
295 checkNotNull(ueSessionId, "UE session ID must be provided");
Daniele Moroa1c7ba42022-01-13 19:16:34 +0100296 if (applicationId == null) {
297 applicationId = DEFAULT_APP_ID;
298 }
tosinski36ba33a2021-11-22 16:53:00 +0100299 checkNotNull(ctrId, "Counter ID must be provided");
Daniele Moro31faf952022-03-09 10:52:32 +0100300 if (!drop) {
301 checkNotNull(trafficClass, "Traffic class must be provided");
302 }
tosinski36ba33a2021-11-22 16:53:00 +0100303 // TODO: should we verify that when dropping no other fields are provided
304 return new UpfTerminationDownlink(
Daniele Moroa1c7ba42022-01-13 19:16:34 +0100305 this.ueSessionId, this.applicationId, this.ctrId, this.trafficClass,
Daniele Moro909b9582022-01-26 15:47:29 +0100306 this.teid, this.qfi, this.appMeterIdx, this.drop
tosinski36ba33a2021-11-22 16:53:00 +0100307 );
308 }
309
310 }
311
312}