blob: 73c96f07396ac4276134b43c1a77886b5ef7cc13 [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;
56 private final String cidr;
Jian Lifc0b8902021-01-12 16:34:49 +090057 private final Set<KubevirtHostRoute> hostRoutes;
Jian Li8fe714d2021-01-11 02:35:06 +090058 private final KubevirtIpPool ipPool;
Jian Li4c35a262021-02-01 20:36:45 +090059 private final Set<IpAddress> dnses;
Jian Li8fe714d2021-01-11 02:35:06 +090060
61 /**
62 * Default constructor.
63 *
64 * @param networkId network identifier
65 * @param type type of network
66 * @param name network name
67 * @param mtu network MTU
68 * @param segmentId segment identifier
69 * @param gatewayIp gateway IP address
70 * @param cidr CIDR of network
Jian Lifc0b8902021-01-12 16:34:49 +090071 * @param hostRoutes a set of host routes
Jian Li8fe714d2021-01-11 02:35:06 +090072 * @param ipPool IP pool
Jian Li4c35a262021-02-01 20:36:45 +090073 * @param dnses a set of DNSes
Jian Li8fe714d2021-01-11 02:35:06 +090074 */
75 public DefaultKubevirtNetwork(String networkId, Type type, String name,
76 Integer mtu, String segmentId, IpAddress gatewayIp,
Jian Lifc0b8902021-01-12 16:34:49 +090077 String cidr, Set<KubevirtHostRoute> hostRoutes,
Jian Li4c35a262021-02-01 20:36:45 +090078 KubevirtIpPool ipPool, Set<IpAddress> dnses) {
Jian Li8fe714d2021-01-11 02:35:06 +090079 this.networkId = networkId;
80 this.type = type;
81 this.name = name;
82 this.mtu = mtu;
83 this.segmentId = segmentId;
84 this.gatewayIp = gatewayIp;
85 this.cidr = cidr;
Jian Lifc0b8902021-01-12 16:34:49 +090086 this.hostRoutes = hostRoutes;
Jian Li8fe714d2021-01-11 02:35:06 +090087 this.ipPool = ipPool;
Jian Li4c35a262021-02-01 20:36:45 +090088 this.dnses = dnses;
Jian Li8fe714d2021-01-11 02:35:06 +090089 }
90
91 @Override
92 public String networkId() {
93 return networkId;
94 }
95
96 @Override
97 public Type type() {
98 return type;
99 }
100
101 @Override
102 public String name() {
103 return name;
104 }
105
106 @Override
107 public Integer mtu() {
108 return mtu;
109 }
110
111 @Override
112 public String segmentId() {
113 return segmentId;
114 }
115
116 @Override
117 public IpAddress gatewayIp() {
118 return gatewayIp;
119 }
120
121 @Override
122 public String cidr() {
123 return cidr;
124 }
125
126 @Override
Jian Lifc0b8902021-01-12 16:34:49 +0900127 public Set<KubevirtHostRoute> hostRoutes() {
Jian Li034820d2021-01-15 16:58:48 +0900128 if (hostRoutes == null || hostRoutes.size() == 0) {
129 return ImmutableSet.of();
130 } else {
131 return ImmutableSet.copyOf(hostRoutes);
132 }
Jian Li8fe714d2021-01-11 02:35:06 +0900133 }
134
135 @Override
136 public KubevirtIpPool ipPool() {
137 return ipPool;
138 }
139
140 @Override
Jian Li4c35a262021-02-01 20:36:45 +0900141 public Set<IpAddress> dnses() {
142 if (dnses == null || dnses.size() == 0) {
143 return ImmutableSet.of();
144 } else {
145 return ImmutableSet.copyOf(dnses);
146 }
147 }
148
149 @Override
Jian Li556709c2021-02-03 17:54:28 +0900150 public String tenantBridgeName() {
151 if (type == VXLAN || type == GRE || type == GENEVE) {
152 return TENANT_BRIDGE_PREFIX + segmentIdHex(segmentId);
153 }
154 return null;
155 }
156
157 @Override
158 public DeviceId tenantDeviceId(String hostname) {
159 if (type == VXLAN || type == GRE || type == GENEVE) {
160 String dpid = genDpidFromName(tenantBridgeName() + "-" + hostname);
Jian Li8f944d42021-03-23 00:43:29 +0900161 return DeviceId.deviceId(dpid);
Jian Li556709c2021-02-03 17:54:28 +0900162 }
163 return null;
164 }
165
166 @Override
Jian Li858ccd72021-02-04 17:25:01 +0900167 public PortNumber tunnelToTenantPort(DeviceId deviceId) {
168 String portName = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(segmentId);
169 Port port = port(deviceId, portName);
170 if (port == null) {
171 return null;
172 } else {
173 return port.number();
174 }
175 }
176
177 @Override
Jian Li8f944d42021-03-23 00:43:29 +0900178 public PortNumber tenantToTunnelPort(DeviceId deviceId) {
179 String portName = TENANT_TO_TUNNEL_PREFIX + segmentIdHex(segmentId);
180 Port port = port(deviceId, portName);
181 if (port == null) {
182 return null;
183 } else {
184 return port.number();
185 }
186 }
187
188 @Override
Jian Li8fe714d2021-01-11 02:35:06 +0900189 public boolean equals(Object o) {
190 if (this == o) {
191 return true;
192 }
193 if (o == null || getClass() != o.getClass()) {
194 return false;
195 }
196 DefaultKubevirtNetwork that = (DefaultKubevirtNetwork) o;
197 return networkId.equals(that.networkId) && type == that.type &&
198 name.equals(that.name) && mtu.equals(that.mtu) &&
199 gatewayIp.equals(that.gatewayIp) &&
Jian Lifc0b8902021-01-12 16:34:49 +0900200 cidr.equals(that.cidr) && hostRoutes.equals(that.hostRoutes) &&
Jian Li4c35a262021-02-01 20:36:45 +0900201 ipPool.equals(that.ipPool) &&
202 dnses.equals(that.dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900203 }
204
205 @Override
206 public int hashCode() {
207 return Objects.hash(networkId, type, name, mtu, segmentId, gatewayIp,
Jian Li4c35a262021-02-01 20:36:45 +0900208 cidr, hostRoutes, ipPool, dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900209 }
210
211 @Override
212 public String toString() {
213 return MoreObjects.toStringHelper(this)
214 .add("networkId", networkId)
215 .add("type", type)
216 .add("name", name)
217 .add("mtu", mtu)
218 .add("segmentId", segmentId)
219 .add("gatewayIp", gatewayIp)
220 .add("cidr", cidr)
Jian Lifc0b8902021-01-12 16:34:49 +0900221 .add("hostRouts", hostRoutes)
Jian Li8fe714d2021-01-11 02:35:06 +0900222 .add("ipPool", ipPool)
Jian Li4c35a262021-02-01 20:36:45 +0900223 .add("dnses", dnses)
Jian Li8fe714d2021-01-11 02:35:06 +0900224 .toString();
225 }
226
Jian Li858ccd72021-02-04 17:25:01 +0900227 private Port port(DeviceId deviceId, String portName) {
228 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
229 return deviceService.getPorts(deviceId).stream()
230 .filter(p -> p.isEnabled() &&
231 Objects.equals(p.annotations().value(PORT_NAME), portName))
232 .findAny().orElse(null);
233 }
234
Jian Li556709c2021-02-03 17:54:28 +0900235 private String segmentIdHex(String segIdStr) {
236 int segId = Integer.parseInt(segIdStr);
237 return String.format("%06x", segId).toLowerCase();
238 }
239
240 private String genDpidFromName(String name) {
241 if (name != null) {
242 String hexString = Integer.toHexString(name.hashCode());
243 return OF_PREFIX + Strings.padStart(hexString, 16, '0');
244 }
245
246 return null;
247 }
248
Jian Li8fe714d2021-01-11 02:35:06 +0900249 /**
250 * Returns new builder instance.
251 *
252 * @return kubevirt port builder
253 */
254 public static Builder builder() {
255 return new Builder();
256 }
257
258 public static final class Builder implements KubevirtNetwork.Builder {
259
260 private String networkId;
261 private Type type;
262 private String name;
263 private Integer mtu;
264 private String segmentId;
265 private IpAddress gatewayIp;
266 private String cidr;
267 private Set<KubevirtHostRoute> hostRouts;
268 private KubevirtIpPool ipPool;
Jian Li4c35a262021-02-01 20:36:45 +0900269 private Set<IpAddress> dnses;
Jian Li8fe714d2021-01-11 02:35:06 +0900270
271 @Override
272 public KubevirtNetwork build() {
273 checkArgument(networkId != null, NOT_NULL_MSG, "networkId");
274 checkArgument(type != null, NOT_NULL_MSG, "type");
275 checkArgument(name != null, NOT_NULL_MSG, "name");
276 checkArgument(mtu != null, NOT_NULL_MSG, "mtu");
277 checkArgument(gatewayIp != null, NOT_NULL_MSG, "gatewayIp");
278 checkArgument(cidr != null, NOT_NULL_MSG, "cidr");
279 checkArgument(ipPool != null, NOT_NULL_MSG, "ipPool");
280
281 if (type != FLAT) {
282 checkArgument(segmentId != null, NOT_NULL_MSG, "segmentId");
283 }
284
Jian Li4c35a262021-02-01 20:36:45 +0900285 if (dnses == null) {
286 dnses = new HashSet<>();
287 }
288
Jian Li8fe714d2021-01-11 02:35:06 +0900289 return new DefaultKubevirtNetwork(networkId, type, name, mtu, segmentId,
Jian Li4c35a262021-02-01 20:36:45 +0900290 gatewayIp, cidr, hostRouts, ipPool, dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900291 }
292
293 @Override
294 public Builder networkId(String networkId) {
295 this.networkId = networkId;
296 return this;
297 }
298
299 @Override
300 public Builder name(String name) {
301 this.name = name;
302 return this;
303 }
304
305 @Override
306 public Builder type(Type type) {
307 this.type = type;
308 return this;
309 }
310
311 @Override
312 public Builder mtu(Integer mtu) {
313 this.mtu = mtu;
314 return this;
315 }
316
317 @Override
318 public Builder segmentId(String segmentId) {
319 this.segmentId = segmentId;
320 return this;
321 }
322
323 @Override
324 public Builder gatewayIp(IpAddress ipAddress) {
325 this.gatewayIp = ipAddress;
326 return this;
327 }
328
329 @Override
330 public Builder cidr(String cidr) {
331 this.cidr = cidr;
332 return this;
333 }
334
335 @Override
336 public Builder ipPool(KubevirtIpPool ipPool) {
337 this.ipPool = ipPool;
338 return this;
339 }
340
341 @Override
342 public Builder hostRoutes(Set<KubevirtHostRoute> hostRoutes) {
343 this.hostRouts = hostRoutes;
344 return this;
345 }
Jian Li4c35a262021-02-01 20:36:45 +0900346
347 @Override
Jian Li1c10cf22021-03-05 01:32:04 +0900348 public Builder dnses(Set<IpAddress> dnses) {
Jian Li4c35a262021-02-01 20:36:45 +0900349 this.dnses = dnses;
350 return this;
351 }
Jian Li8fe714d2021-01-11 02:35:06 +0900352 }
353}