blob: e903d30ae9fd4c69b381f4c266f01bb18ddf7bf7 [file] [log] [blame]
Daniele Morodbcffda2021-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
tosinskia57652d2021-11-22 16:53:00 +010019import com.google.common.annotations.Beta;
Daniele Morodbcffda2021-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/**
Daniele Moro3894e9e2022-02-10 18:21:01 +010028 * A UPF device interface, such as a N3, or UE IP address pool (N6).
Daniele Morodbcffda2021-06-11 16:41:48 +020029 */
tosinskia57652d2021-11-22 16:53:00 +010030@Beta
31public final class UpfInterface implements UpfEntity {
Daniele Morodbcffda2021-06-11 16:41:48 +020032 private final Ip4Prefix prefix;
33 private final Type type;
Daniele Morode1f1f72022-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 Morodbcffda2021-06-11 16:41:48 +020036
Daniele Morode1f1f72022-01-26 16:47:08 +010037 private UpfInterface(Ip4Prefix prefix, Type type, int sliceId) {
Daniele Morodbcffda2021-06-11 16:41:48 +020038 this.prefix = prefix;
39 this.type = type;
Daniele Morode1f1f72022-01-26 16:47:08 +010040 this.sliceId = sliceId;
Daniele Morodbcffda2021-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 Morode1f1f72022-01-26 16:47:08 +010049 return String.format("UpfInterface(type=%s, prefix=%s, slice_id=%s)", type.toString(), prefix, sliceId);
Daniele Morodbcffda2021-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 Morode1f1f72022-01-26 16:47:08 +010064 return this.type.equals(that.type) &&
65 this.prefix.equals(that.prefix) &&
66 this.sliceId == that.sliceId;
Daniele Morodbcffda2021-06-11 16:41:48 +020067 }
68
69 @Override
70 public int hashCode() {
Daniele Morode1f1f72022-01-26 16:47:08 +010071 return Objects.hash(prefix, type, sliceId);
Daniele Morodbcffda2021-06-11 16:41:48 +020072 }
73
74 /**
Daniele Moro3894e9e2022-02-10 18:21:01 +010075 * Create access-facing UPF Interface (N3) from the given address, which will be treated as a /32 prefix.
76 *
77 * @param address the address of the new access-facing interface (N3 interface)
78 * @param sliceId the slice id of the new interface
Daniele Morodbcffda2021-06-11 16:41:48 +020079 * @return a new UPF interface
80 */
Daniele Moro3894e9e2022-02-10 18:21:01 +010081 public static UpfInterface createN3From(Ip4Address address, int sliceId) {
Daniele Morode1f1f72022-01-26 16:47:08 +010082 return builder()
83 .setAccess()
84 .setPrefix(Ip4Prefix.valueOf(address, 32))
85 .setSliceId(sliceId)
86 .build();
Daniele Morodbcffda2021-06-11 16:41:48 +020087 }
88
89 /**
Daniele Moro3894e9e2022-02-10 18:21:01 +010090 * Create a core-facing UPF Interface (N6) from the given IP prefix.
Daniele Morodbcffda2021-06-11 16:41:48 +020091 *
Daniele Moro3894e9e2022-02-10 18:21:01 +010092 * @param prefix the prefix of the new core-facing interface (N6 interface)
93 * @param sliceId the slice id of the new interface
Daniele Morodbcffda2021-06-11 16:41:48 +020094 * @return a new UPF interface
95 */
Daniele Morode1f1f72022-01-26 16:47:08 +010096 public static UpfInterface createUePoolFrom(Ip4Prefix prefix, int sliceId) {
97 return builder()
98 .setCore()
99 .setPrefix(prefix)
100 .setSliceId(sliceId)
101 .build();
Daniele Morodbcffda2021-06-11 16:41:48 +0200102 }
103
104 /**
105 * Create a dbuf-receiving UPF interface from the given IP address.
106 *
107 * @param address the address of the dbuf-receiving interface
Daniele Moro3894e9e2022-02-10 18:21:01 +0100108 * @param sliceId the slice id of the new interface
Daniele Morodbcffda2021-06-11 16:41:48 +0200109 * @return a new UPF interface
110 */
Daniele Morode1f1f72022-01-26 16:47:08 +0100111 public static UpfInterface createDbufReceiverFrom(Ip4Address address, int sliceId) {
112 return builder()
113 .setDbufReceiver()
114 .setAddress(address)
115 .setSliceId(sliceId)
116 .build();
Daniele Morodbcffda2021-06-11 16:41:48 +0200117 }
118
119 /**
120 * Get the IP prefix of this interface.
121 *
122 * @return the interface prefix
123 */
124 public Ip4Prefix prefix() {
125 return prefix;
126 }
127
128 /**
Daniele Morode1f1f72022-01-26 16:47:08 +0100129 * Get the slice ID of this interface.
130 *
131 * @return the slice ID
132 */
133 public int sliceId() {
134 return sliceId;
135 }
136
137 /**
Daniele Morodbcffda2021-06-11 16:41:48 +0200138 * Check if this UPF interface is for packets traveling from UEs.
Daniele Moro3894e9e2022-02-10 18:21:01 +0100139 * This will be true for N3 interface table entries.
Daniele Morodbcffda2021-06-11 16:41:48 +0200140 *
141 * @return true if interface receives from access
142 */
143 public boolean isAccess() {
144 return type == Type.ACCESS;
145 }
146
147 /**
148 * Check if this UPF interface is for packets traveling towards UEs.
149 * This will be true for UE IP address pool table entries.
150 *
151 * @return true if interface receives from core
152 */
153 public boolean isCore() {
154 return type == Type.CORE;
155 }
156
Daniele Morodbcffda2021-06-11 16:41:48 +0200157 /**
158 * Check if this UPF interface is for receiving buffered packets as they are released from the dbuf
159 * buffering device.
160 *
161 * @return true if interface receives from dbuf
162 */
163 public boolean isDbufReceiver() {
164 return type == Type.DBUF;
165 }
166
167 /**
168 * Get the IPv4 prefix of this UPF interface.
169 *
170 * @return the interface prefix
171 */
172 public Ip4Prefix getPrefix() {
173 return this.prefix;
174 }
175
tosinskia57652d2021-11-22 16:53:00 +0100176 @Override
177 public UpfEntityType type() {
178 return UpfEntityType.INTERFACE;
179 }
180
Daniele Morodbcffda2021-06-11 16:41:48 +0200181 public enum Type {
182 /**
183 * Unknown UPF interface type.
184 */
185 UNKNOWN,
186
187 /**
188 * Interface that receives GTP encapsulated packets.
Daniele Moro3894e9e2022-02-10 18:21:01 +0100189 * This is the type of the N3 interface.
Daniele Morodbcffda2021-06-11 16:41:48 +0200190 */
191 ACCESS,
192
193 /**
194 * Interface that receives unencapsulated packets from the core of the network.
Daniele Moro3894e9e2022-02-10 18:21:01 +0100195 * This is the type of UE IP address pool interfaces (N6).
Daniele Morodbcffda2021-06-11 16:41:48 +0200196 */
197 CORE,
198
199 /**
200 * Interface that receives buffered packets as they are drained from a dbuf device.
201 */
202 DBUF
203 }
204
205 public static class Builder {
206 private Ip4Prefix prefix;
207 private Type type;
Daniele Morode1f1f72022-01-26 16:47:08 +0100208 private Integer sliceId;
Daniele Morodbcffda2021-06-11 16:41:48 +0200209
210 public Builder() {
211 type = Type.UNKNOWN;
212 }
213
214 /**
215 * Set the IPv4 prefix of this interface.
216 *
217 * @param prefix the interface prefix
218 * @return this builder object
219 */
220 public Builder setPrefix(Ip4Prefix prefix) {
221 this.prefix = prefix;
222 return this;
223 }
224
225 /**
Daniele Morode1f1f72022-01-26 16:47:08 +0100226 * Set the slice ID of this interface.
227 *
228 * @param sliceId the slice ID
229 * @return this builder object
230 */
231 public Builder setSliceId(int sliceId) {
232 this.sliceId = sliceId;
233 return this;
234 }
235
236 /**
Daniele Morodbcffda2021-06-11 16:41:48 +0200237 * Set the IPv4 prefix of this interface, by turning the given address into a /32 prefix.
238 *
239 * @param address the interface address that will become a /32 prefix
240 * @return this builder object
241 */
242 public Builder setAddress(Ip4Address address) {
243 this.prefix = Ip4Prefix.valueOf(address, 32);
244 return this;
245 }
246
247 /**
Daniele Moro3894e9e2022-02-10 18:21:01 +0100248 * Make this an access-facing interface (N3).
Daniele Morodbcffda2021-06-11 16:41:48 +0200249 *
250 * @return this builder object
251 */
252 public Builder setAccess() {
253 this.type = Type.ACCESS;
254 return this;
255 }
256
257 /**
Daniele Moro3894e9e2022-02-10 18:21:01 +0100258 * Make this a core-facing interface (N6).
Daniele Morodbcffda2021-06-11 16:41:48 +0200259 *
260 * @return this builder object
261 */
262 public Builder setCore() {
263 this.type = Type.CORE;
264 return this;
265 }
266
267 /**
268 * Make this a dbuf-facing interface.
269 *
270 * @return this builder object
271 */
272 public Builder setDbufReceiver() {
273 this.type = Type.DBUF;
274 return this;
275 }
276
277 public UpfInterface build() {
Daniele Morode1f1f72022-01-26 16:47:08 +0100278 checkNotNull(prefix, "The IPv4 prefix must be provided");
279 checkNotNull(sliceId, "Slice ID must be provided");
280 return new UpfInterface(prefix, type, sliceId);
Daniele Morodbcffda2021-06-11 16:41:48 +0200281 }
282 }
283}