blob: cf10ae17afba318d92879bdb7e84fd4f288cf522 [file] [log] [blame]
Daniele Moro5e66f982021-06-11 16:41:48 +02001/*
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
tosinski36ba33a2021-11-22 16:53:00 +010019import com.google.common.annotations.Beta;
Daniele Moro5e66f982021-06-11 16:41:48 +020020import org.onlab.packet.Ip4Address;
21import org.onlab.packet.Ip4Prefix;
22
23import java.util.Objects;
24
25import static com.google.common.base.Preconditions.checkNotNull;
26
27/**
28 * A UPF device interface, such as a S1U or UE IP address pool.
29 */
tosinski36ba33a2021-11-22 16:53:00 +010030@Beta
31public final class UpfInterface implements UpfEntity {
Daniele Moro5e66f982021-06-11 16:41:48 +020032 private final Ip4Prefix prefix;
33 private final Type type;
Daniele Morof3a5ab02022-01-26 16:47:08 +010034 // TODO: move to SliceId object when slice APIs will be promoted to ONOS core.
35 private final int sliceId;
Daniele Moro5e66f982021-06-11 16:41:48 +020036
Daniele Morof3a5ab02022-01-26 16:47:08 +010037 private UpfInterface(Ip4Prefix prefix, Type type, int sliceId) {
Daniele Moro5e66f982021-06-11 16:41:48 +020038 this.prefix = prefix;
39 this.type = type;
Daniele Morof3a5ab02022-01-26 16:47:08 +010040 this.sliceId = sliceId;
Daniele Moro5e66f982021-06-11 16:41:48 +020041 }
42
43 public static Builder builder() {
44 return new Builder();
45 }
46
47 @Override
48 public String toString() {
Daniele Morof3a5ab02022-01-26 16:47:08 +010049 return String.format("UpfInterface(type=%s, prefix=%s, slice_id=%s)", type.toString(), prefix, sliceId);
Daniele Moro5e66f982021-06-11 16:41:48 +020050 }
51
52 @Override
53 public boolean equals(Object obj) {
54 if (obj == this) {
55 return true;
56 }
57 if (obj == null) {
58 return false;
59 }
60 if (getClass() != obj.getClass()) {
61 return false;
62 }
63 UpfInterface that = (UpfInterface) obj;
Daniele Morof3a5ab02022-01-26 16:47:08 +010064 return this.type.equals(that.type) &&
65 this.prefix.equals(that.prefix) &&
66 this.sliceId == that.sliceId;
Daniele Moro5e66f982021-06-11 16:41:48 +020067 }
68
69 @Override
70 public int hashCode() {
Daniele Morof3a5ab02022-01-26 16:47:08 +010071 return Objects.hash(prefix, type, sliceId);
Daniele Moro5e66f982021-06-11 16:41:48 +020072 }
73
74 /**
75 * Create a core-facing UPF Interface from the given address, which will be treated as a /32 prefix.
Daniele Moro5e66f982021-06-11 16:41:48 +020076 * @param address the address of the new core-facing interface
Daniele Morof3a5ab02022-01-26 16:47:08 +010077 * @param sliceId the slice if of the new interface
Daniele Moro5e66f982021-06-11 16:41:48 +020078 * @return a new UPF interface
79 */
Daniele Morof3a5ab02022-01-26 16:47:08 +010080 public static UpfInterface createS1uFrom(Ip4Address address, int sliceId) {
81 return builder()
82 .setAccess()
83 .setPrefix(Ip4Prefix.valueOf(address, 32))
84 .setSliceId(sliceId)
85 .build();
Daniele Moro5e66f982021-06-11 16:41:48 +020086 }
87
88 /**
89 * Create a core-facing UPF Interface from the given IP prefix.
90 *
91 * @param prefix the prefix of the new core-facing interface
Daniele Morof3a5ab02022-01-26 16:47:08 +010092 * @param sliceId the slice if of the new interface
Daniele Moro5e66f982021-06-11 16:41:48 +020093 * @return a new UPF interface
94 */
Daniele Morof3a5ab02022-01-26 16:47:08 +010095 public static UpfInterface createUePoolFrom(Ip4Prefix prefix, int sliceId) {
96 return builder()
97 .setCore()
98 .setPrefix(prefix)
99 .setSliceId(sliceId)
100 .build();
Daniele Moro5e66f982021-06-11 16:41:48 +0200101 }
102
103 /**
104 * Create a dbuf-receiving UPF interface from the given IP address.
105 *
106 * @param address the address of the dbuf-receiving interface
Daniele Morof3a5ab02022-01-26 16:47:08 +0100107 * @param sliceId the slice if of the new interface
Daniele Moro5e66f982021-06-11 16:41:48 +0200108 * @return a new UPF interface
109 */
Daniele Morof3a5ab02022-01-26 16:47:08 +0100110 public static UpfInterface createDbufReceiverFrom(Ip4Address address, int sliceId) {
111 return builder()
112 .setDbufReceiver()
113 .setAddress(address)
114 .setSliceId(sliceId)
115 .build();
Daniele Moro5e66f982021-06-11 16:41:48 +0200116 }
117
118 /**
119 * Get the IP prefix of this interface.
120 *
121 * @return the interface prefix
122 */
123 public Ip4Prefix prefix() {
124 return prefix;
125 }
126
127 /**
Daniele Morof3a5ab02022-01-26 16:47:08 +0100128 * Get the slice ID of this interface.
129 *
130 * @return the slice ID
131 */
132 public int sliceId() {
133 return sliceId;
134 }
135
136 /**
Daniele Moro5e66f982021-06-11 16:41:48 +0200137 * Check if this UPF interface is for packets traveling from UEs.
138 * This will be true for S1U interface table entries.
139 *
140 * @return true if interface receives from access
141 */
142 public boolean isAccess() {
143 return type == Type.ACCESS;
144 }
145
146 /**
147 * Check if this UPF interface is for packets traveling towards UEs.
148 * This will be true for UE IP address pool table entries.
149 *
150 * @return true if interface receives from core
151 */
152 public boolean isCore() {
153 return type == Type.CORE;
154 }
155
Daniele Moro5e66f982021-06-11 16:41:48 +0200156 /**
157 * Check if this UPF interface is for receiving buffered packets as they are released from the dbuf
158 * buffering device.
159 *
160 * @return true if interface receives from dbuf
161 */
162 public boolean isDbufReceiver() {
163 return type == Type.DBUF;
164 }
165
166 /**
167 * Get the IPv4 prefix of this UPF interface.
168 *
169 * @return the interface prefix
170 */
171 public Ip4Prefix getPrefix() {
172 return this.prefix;
173 }
174
tosinski36ba33a2021-11-22 16:53:00 +0100175 @Override
176 public UpfEntityType type() {
177 return UpfEntityType.INTERFACE;
178 }
179
Daniele Moro5e66f982021-06-11 16:41:48 +0200180 public enum Type {
181 /**
182 * Unknown UPF interface type.
183 */
184 UNKNOWN,
185
186 /**
187 * Interface that receives GTP encapsulated packets.
188 * This is the type of the S1U interface.
189 */
190 ACCESS,
191
192 /**
193 * Interface that receives unencapsulated packets from the core of the network.
194 * This is the type of UE IP address pool interfaces.
195 */
196 CORE,
197
198 /**
199 * Interface that receives buffered packets as they are drained from a dbuf device.
200 */
201 DBUF
202 }
203
204 public static class Builder {
205 private Ip4Prefix prefix;
206 private Type type;
Daniele Morof3a5ab02022-01-26 16:47:08 +0100207 private Integer sliceId;
Daniele Moro5e66f982021-06-11 16:41:48 +0200208
209 public Builder() {
210 type = Type.UNKNOWN;
211 }
212
213 /**
214 * Set the IPv4 prefix of this interface.
215 *
216 * @param prefix the interface prefix
217 * @return this builder object
218 */
219 public Builder setPrefix(Ip4Prefix prefix) {
220 this.prefix = prefix;
221 return this;
222 }
223
224 /**
Daniele Morof3a5ab02022-01-26 16:47:08 +0100225 * Set the slice ID of this interface.
226 *
227 * @param sliceId the slice ID
228 * @return this builder object
229 */
230 public Builder setSliceId(int sliceId) {
231 this.sliceId = sliceId;
232 return this;
233 }
234
235 /**
Daniele Moro5e66f982021-06-11 16:41:48 +0200236 * Set the IPv4 prefix of this interface, by turning the given address into a /32 prefix.
237 *
238 * @param address the interface address that will become a /32 prefix
239 * @return this builder object
240 */
241 public Builder setAddress(Ip4Address address) {
242 this.prefix = Ip4Prefix.valueOf(address, 32);
243 return this;
244 }
245
246 /**
247 * Make this an access-facing interface.
248 *
249 * @return this builder object
250 */
251 public Builder setAccess() {
252 this.type = Type.ACCESS;
253 return this;
254 }
255
256 /**
257 * Make this a core-facing interface.
258 *
259 * @return this builder object
260 */
261 public Builder setCore() {
262 this.type = Type.CORE;
263 return this;
264 }
265
266 /**
267 * Make this a dbuf-facing interface.
268 *
269 * @return this builder object
270 */
271 public Builder setDbufReceiver() {
272 this.type = Type.DBUF;
273 return this;
274 }
275
276 public UpfInterface build() {
Daniele Morof3a5ab02022-01-26 16:47:08 +0100277 checkNotNull(prefix, "The IPv4 prefix must be provided");
278 checkNotNull(sliceId, "Slice ID must be provided");
279 return new UpfInterface(prefix, type, sliceId);
Daniele Moro5e66f982021-06-11 16:41:48 +0200280 }
281 }
282}