blob: 2745e46a5ea740d2445c577e79701e77aac4b536 [file] [log] [blame]
Jian Li8fe714d2021-01-11 02:35:06 +09001/*
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 */
16package org.onosproject.kubevirtnetworking.api;
17
18import com.google.common.base.MoreObjects;
Jian Li556709c2021-02-03 17:54:28 +090019import com.google.common.base.Strings;
Jian Li8fe714d2021-01-11 02:35:06 +090020import com.google.common.collect.ImmutableSet;
Jian Li858ccd72021-02-04 17:25:01 +090021import org.onlab.osgi.DefaultServiceDirectory;
Jian Li8fe714d2021-01-11 02:35:06 +090022import org.onlab.packet.IpAddress;
Jian Li556709c2021-02-03 17:54:28 +090023import org.onosproject.net.DeviceId;
Jian Li858ccd72021-02-04 17:25:01 +090024import org.onosproject.net.Port;
25import org.onosproject.net.PortNumber;
26import org.onosproject.net.device.DeviceService;
Jian Li8fe714d2021-01-11 02:35:06 +090027
Jian Li4c35a262021-02-01 20:36:45 +090028import java.util.HashSet;
Jian Li8fe714d2021-01-11 02:35:06 +090029import java.util.Objects;
30import java.util.Set;
31
32import static com.google.common.base.Preconditions.checkArgument;
Jian Li8f944d42021-03-23 00:43:29 +090033import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_TO_TUNNEL_PREFIX;
Jian Li858ccd72021-02-04 17:25:01 +090034import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_TO_TENANT_PREFIX;
Jian Li8fe714d2021-01-11 02:35:06 +090035import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.FLAT;
Jian Li556709c2021-02-03 17:54:28 +090036import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GENEVE;
37import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GRE;
38import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.VXLAN;
Jian Li858ccd72021-02-04 17:25:01 +090039import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Jian Li8fe714d2021-01-11 02:35:06 +090040
41/**
42 * Default implementation class of kubevirt network.
43 */
44public final class DefaultKubevirtNetwork implements KubevirtNetwork {
45
46 private static final String NOT_NULL_MSG = "Network % cannot be null";
Jian Li556709c2021-02-03 17:54:28 +090047 private static final String TENANT_BRIDGE_PREFIX = "br-int-";
48 private static final String OF_PREFIX = "of:";
Jian Li8fe714d2021-01-11 02:35:06 +090049
50 private final String networkId;
51 private final Type type;
52 private final String name;
53 private final Integer mtu;
54 private final String segmentId;
55 private final IpAddress gatewayIp;
Jian Lie2abe812021-08-12 18:03:30 +090056 private final boolean defaultRoute;
Jian Li8fe714d2021-01-11 02:35:06 +090057 private final String cidr;
Jian Lifc0b8902021-01-12 16:34:49 +090058 private final Set<KubevirtHostRoute> hostRoutes;
Jian Li8fe714d2021-01-11 02:35:06 +090059 private final KubevirtIpPool ipPool;
Jian Li4c35a262021-02-01 20:36:45 +090060 private final Set<IpAddress> dnses;
Jian Li8fe714d2021-01-11 02:35:06 +090061
62 /**
63 * Default constructor.
64 *
65 * @param networkId network identifier
66 * @param type type of network
67 * @param name network name
68 * @param mtu network MTU
69 * @param segmentId segment identifier
70 * @param gatewayIp gateway IP address
Jian Lie2abe812021-08-12 18:03:30 +090071 * @param defaultRoute default route
Jian Li8fe714d2021-01-11 02:35:06 +090072 * @param cidr CIDR of network
Jian Lifc0b8902021-01-12 16:34:49 +090073 * @param hostRoutes a set of host routes
Jian Li8fe714d2021-01-11 02:35:06 +090074 * @param ipPool IP pool
Jian Li4c35a262021-02-01 20:36:45 +090075 * @param dnses a set of DNSes
Jian Li8fe714d2021-01-11 02:35:06 +090076 */
77 public DefaultKubevirtNetwork(String networkId, Type type, String name,
78 Integer mtu, String segmentId, IpAddress gatewayIp,
Jian Lie2abe812021-08-12 18:03:30 +090079 boolean defaultRoute, String cidr,
80 Set<KubevirtHostRoute> hostRoutes,
Jian Li4c35a262021-02-01 20:36:45 +090081 KubevirtIpPool ipPool, Set<IpAddress> dnses) {
Jian Li8fe714d2021-01-11 02:35:06 +090082 this.networkId = networkId;
83 this.type = type;
84 this.name = name;
85 this.mtu = mtu;
86 this.segmentId = segmentId;
87 this.gatewayIp = gatewayIp;
Jian Lie2abe812021-08-12 18:03:30 +090088 this.defaultRoute = defaultRoute;
Jian Li8fe714d2021-01-11 02:35:06 +090089 this.cidr = cidr;
Jian Lifc0b8902021-01-12 16:34:49 +090090 this.hostRoutes = hostRoutes;
Jian Li8fe714d2021-01-11 02:35:06 +090091 this.ipPool = ipPool;
Jian Li4c35a262021-02-01 20:36:45 +090092 this.dnses = dnses;
Jian Li8fe714d2021-01-11 02:35:06 +090093 }
94
95 @Override
96 public String networkId() {
97 return networkId;
98 }
99
100 @Override
101 public Type type() {
102 return type;
103 }
104
105 @Override
106 public String name() {
107 return name;
108 }
109
110 @Override
111 public Integer mtu() {
112 return mtu;
113 }
114
115 @Override
116 public String segmentId() {
117 return segmentId;
118 }
119
120 @Override
121 public IpAddress gatewayIp() {
122 return gatewayIp;
123 }
124
125 @Override
126 public String cidr() {
127 return cidr;
128 }
129
130 @Override
Jian Lifc0b8902021-01-12 16:34:49 +0900131 public Set<KubevirtHostRoute> hostRoutes() {
Jian Li034820d2021-01-15 16:58:48 +0900132 if (hostRoutes == null || hostRoutes.size() == 0) {
133 return ImmutableSet.of();
134 } else {
135 return ImmutableSet.copyOf(hostRoutes);
136 }
Jian Li8fe714d2021-01-11 02:35:06 +0900137 }
138
139 @Override
Jian Lie2abe812021-08-12 18:03:30 +0900140 public boolean defaultRoute() {
141 return defaultRoute;
142 }
143
144 @Override
Jian Li8fe714d2021-01-11 02:35:06 +0900145 public KubevirtIpPool ipPool() {
146 return ipPool;
147 }
148
149 @Override
Jian Li4c35a262021-02-01 20:36:45 +0900150 public Set<IpAddress> dnses() {
151 if (dnses == null || dnses.size() == 0) {
152 return ImmutableSet.of();
153 } else {
154 return ImmutableSet.copyOf(dnses);
155 }
156 }
157
158 @Override
Jian Li556709c2021-02-03 17:54:28 +0900159 public String tenantBridgeName() {
160 if (type == VXLAN || type == GRE || type == GENEVE) {
161 return TENANT_BRIDGE_PREFIX + segmentIdHex(segmentId);
162 }
163 return null;
164 }
165
166 @Override
167 public DeviceId tenantDeviceId(String hostname) {
168 if (type == VXLAN || type == GRE || type == GENEVE) {
169 String dpid = genDpidFromName(tenantBridgeName() + "-" + hostname);
Jian Li8f944d42021-03-23 00:43:29 +0900170 return DeviceId.deviceId(dpid);
Jian Li556709c2021-02-03 17:54:28 +0900171 }
172 return null;
173 }
174
175 @Override
Jian Li858ccd72021-02-04 17:25:01 +0900176 public PortNumber tunnelToTenantPort(DeviceId deviceId) {
177 String portName = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(segmentId);
178 Port port = port(deviceId, portName);
179 if (port == null) {
180 return null;
181 } else {
182 return port.number();
183 }
184 }
185
186 @Override
Jian Li8f944d42021-03-23 00:43:29 +0900187 public PortNumber tenantToTunnelPort(DeviceId deviceId) {
188 String portName = TENANT_TO_TUNNEL_PREFIX + segmentIdHex(segmentId);
189 Port port = port(deviceId, portName);
190 if (port == null) {
191 return null;
192 } else {
193 return port.number();
194 }
195 }
196
197 @Override
Jian Li8fe714d2021-01-11 02:35:06 +0900198 public boolean equals(Object o) {
199 if (this == o) {
200 return true;
201 }
202 if (o == null || getClass() != o.getClass()) {
203 return false;
204 }
205 DefaultKubevirtNetwork that = (DefaultKubevirtNetwork) o;
206 return networkId.equals(that.networkId) && type == that.type &&
207 name.equals(that.name) && mtu.equals(that.mtu) &&
Jian Lie2abe812021-08-12 18:03:30 +0900208 gatewayIp.equals(that.gatewayIp) && defaultRoute == that.defaultRoute &&
Jian Lifc0b8902021-01-12 16:34:49 +0900209 cidr.equals(that.cidr) && hostRoutes.equals(that.hostRoutes) &&
Jian Li4c35a262021-02-01 20:36:45 +0900210 ipPool.equals(that.ipPool) &&
211 dnses.equals(that.dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900212 }
213
214 @Override
215 public int hashCode() {
216 return Objects.hash(networkId, type, name, mtu, segmentId, gatewayIp,
Jian Lie2abe812021-08-12 18:03:30 +0900217 defaultRoute, cidr, hostRoutes, ipPool, dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900218 }
219
220 @Override
221 public String toString() {
222 return MoreObjects.toStringHelper(this)
223 .add("networkId", networkId)
224 .add("type", type)
225 .add("name", name)
226 .add("mtu", mtu)
227 .add("segmentId", segmentId)
228 .add("gatewayIp", gatewayIp)
Jian Lie2abe812021-08-12 18:03:30 +0900229 .add("defaultRoute", defaultRoute)
Jian Li8fe714d2021-01-11 02:35:06 +0900230 .add("cidr", cidr)
Jian Lifc0b8902021-01-12 16:34:49 +0900231 .add("hostRouts", hostRoutes)
Jian Li8fe714d2021-01-11 02:35:06 +0900232 .add("ipPool", ipPool)
Jian Li4c35a262021-02-01 20:36:45 +0900233 .add("dnses", dnses)
Jian Li8fe714d2021-01-11 02:35:06 +0900234 .toString();
235 }
236
Jian Li858ccd72021-02-04 17:25:01 +0900237 private Port port(DeviceId deviceId, String portName) {
238 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
239 return deviceService.getPorts(deviceId).stream()
240 .filter(p -> p.isEnabled() &&
241 Objects.equals(p.annotations().value(PORT_NAME), portName))
242 .findAny().orElse(null);
243 }
244
Jian Li556709c2021-02-03 17:54:28 +0900245 private String segmentIdHex(String segIdStr) {
246 int segId = Integer.parseInt(segIdStr);
247 return String.format("%06x", segId).toLowerCase();
248 }
249
250 private String genDpidFromName(String name) {
251 if (name != null) {
252 String hexString = Integer.toHexString(name.hashCode());
253 return OF_PREFIX + Strings.padStart(hexString, 16, '0');
254 }
255
256 return null;
257 }
258
Jian Li8fe714d2021-01-11 02:35:06 +0900259 /**
260 * Returns new builder instance.
261 *
262 * @return kubevirt port builder
263 */
264 public static Builder builder() {
265 return new Builder();
266 }
267
268 public static final class Builder implements KubevirtNetwork.Builder {
269
270 private String networkId;
271 private Type type;
272 private String name;
273 private Integer mtu;
274 private String segmentId;
275 private IpAddress gatewayIp;
Jian Lie2abe812021-08-12 18:03:30 +0900276 private boolean defaultRoute;
Jian Li8fe714d2021-01-11 02:35:06 +0900277 private String cidr;
278 private Set<KubevirtHostRoute> hostRouts;
279 private KubevirtIpPool ipPool;
Jian Li4c35a262021-02-01 20:36:45 +0900280 private Set<IpAddress> dnses;
Jian Li8fe714d2021-01-11 02:35:06 +0900281
282 @Override
283 public KubevirtNetwork build() {
284 checkArgument(networkId != null, NOT_NULL_MSG, "networkId");
285 checkArgument(type != null, NOT_NULL_MSG, "type");
286 checkArgument(name != null, NOT_NULL_MSG, "name");
287 checkArgument(mtu != null, NOT_NULL_MSG, "mtu");
Jian Li8fe714d2021-01-11 02:35:06 +0900288 checkArgument(cidr != null, NOT_NULL_MSG, "cidr");
289 checkArgument(ipPool != null, NOT_NULL_MSG, "ipPool");
290
291 if (type != FLAT) {
292 checkArgument(segmentId != null, NOT_NULL_MSG, "segmentId");
293 }
294
Jian Li4c35a262021-02-01 20:36:45 +0900295 if (dnses == null) {
296 dnses = new HashSet<>();
297 }
298
Jian Li8fe714d2021-01-11 02:35:06 +0900299 return new DefaultKubevirtNetwork(networkId, type, name, mtu, segmentId,
Jian Lie2abe812021-08-12 18:03:30 +0900300 gatewayIp, defaultRoute, cidr, hostRouts, ipPool, dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900301 }
302
303 @Override
304 public Builder networkId(String networkId) {
305 this.networkId = networkId;
306 return this;
307 }
308
309 @Override
310 public Builder name(String name) {
311 this.name = name;
312 return this;
313 }
314
315 @Override
316 public Builder type(Type type) {
317 this.type = type;
318 return this;
319 }
320
321 @Override
322 public Builder mtu(Integer mtu) {
323 this.mtu = mtu;
324 return this;
325 }
326
327 @Override
328 public Builder segmentId(String segmentId) {
329 this.segmentId = segmentId;
330 return this;
331 }
332
333 @Override
334 public Builder gatewayIp(IpAddress ipAddress) {
335 this.gatewayIp = ipAddress;
336 return this;
337 }
338
339 @Override
Jian Lie2abe812021-08-12 18:03:30 +0900340 public KubevirtNetwork.Builder defaultRoute(boolean flag) {
341 this.defaultRoute = flag;
342 return this;
343 }
344
345 @Override
Jian Li8fe714d2021-01-11 02:35:06 +0900346 public Builder cidr(String cidr) {
347 this.cidr = cidr;
348 return this;
349 }
350
351 @Override
352 public Builder ipPool(KubevirtIpPool ipPool) {
353 this.ipPool = ipPool;
354 return this;
355 }
356
357 @Override
358 public Builder hostRoutes(Set<KubevirtHostRoute> hostRoutes) {
359 this.hostRouts = hostRoutes;
360 return this;
361 }
Jian Li4c35a262021-02-01 20:36:45 +0900362
363 @Override
Jian Li1c10cf22021-03-05 01:32:04 +0900364 public Builder dnses(Set<IpAddress> dnses) {
Jian Li4c35a262021-02-01 20:36:45 +0900365 this.dnses = dnses;
366 return this;
367 }
Jian Li8fe714d2021-01-11 02:35:06 +0900368 }
369}