blob: 35d367f91723458689272a59075eaf0e66843453 [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 Li858ccd72021-02-04 17:25:01 +090033import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_TO_TENANT_PREFIX;
Jian Li8fe714d2021-01-11 02:35:06 +090034import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.FLAT;
Jian Li556709c2021-02-03 17:54:28 +090035import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GENEVE;
36import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GRE;
37import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.VXLAN;
Jian Li858ccd72021-02-04 17:25:01 +090038import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Jian Li8fe714d2021-01-11 02:35:06 +090039
40/**
41 * Default implementation class of kubevirt network.
42 */
43public final class DefaultKubevirtNetwork implements KubevirtNetwork {
44
45 private static final String NOT_NULL_MSG = "Network % cannot be null";
Jian Li556709c2021-02-03 17:54:28 +090046 private static final String TENANT_BRIDGE_PREFIX = "br-int-";
47 private static final String OF_PREFIX = "of:";
Jian Li8fe714d2021-01-11 02:35:06 +090048
49 private final String networkId;
50 private final Type type;
51 private final String name;
52 private final Integer mtu;
53 private final String segmentId;
54 private final IpAddress gatewayIp;
55 private final String cidr;
Jian Lifc0b8902021-01-12 16:34:49 +090056 private final Set<KubevirtHostRoute> hostRoutes;
Jian Li8fe714d2021-01-11 02:35:06 +090057 private final KubevirtIpPool ipPool;
Jian Li4c35a262021-02-01 20:36:45 +090058 private final Set<IpAddress> dnses;
Jian Li8fe714d2021-01-11 02:35:06 +090059
60 /**
61 * Default constructor.
62 *
63 * @param networkId network identifier
64 * @param type type of network
65 * @param name network name
66 * @param mtu network MTU
67 * @param segmentId segment identifier
68 * @param gatewayIp gateway IP address
69 * @param cidr CIDR of network
Jian Lifc0b8902021-01-12 16:34:49 +090070 * @param hostRoutes a set of host routes
Jian Li8fe714d2021-01-11 02:35:06 +090071 * @param ipPool IP pool
Jian Li4c35a262021-02-01 20:36:45 +090072 * @param dnses a set of DNSes
Jian Li8fe714d2021-01-11 02:35:06 +090073 */
74 public DefaultKubevirtNetwork(String networkId, Type type, String name,
75 Integer mtu, String segmentId, IpAddress gatewayIp,
Jian Lifc0b8902021-01-12 16:34:49 +090076 String cidr, Set<KubevirtHostRoute> hostRoutes,
Jian Li4c35a262021-02-01 20:36:45 +090077 KubevirtIpPool ipPool, Set<IpAddress> dnses) {
Jian Li8fe714d2021-01-11 02:35:06 +090078 this.networkId = networkId;
79 this.type = type;
80 this.name = name;
81 this.mtu = mtu;
82 this.segmentId = segmentId;
83 this.gatewayIp = gatewayIp;
84 this.cidr = cidr;
Jian Lifc0b8902021-01-12 16:34:49 +090085 this.hostRoutes = hostRoutes;
Jian Li8fe714d2021-01-11 02:35:06 +090086 this.ipPool = ipPool;
Jian Li4c35a262021-02-01 20:36:45 +090087 this.dnses = dnses;
Jian Li8fe714d2021-01-11 02:35:06 +090088 }
89
90 @Override
91 public String networkId() {
92 return networkId;
93 }
94
95 @Override
96 public Type type() {
97 return type;
98 }
99
100 @Override
101 public String name() {
102 return name;
103 }
104
105 @Override
106 public Integer mtu() {
107 return mtu;
108 }
109
110 @Override
111 public String segmentId() {
112 return segmentId;
113 }
114
115 @Override
116 public IpAddress gatewayIp() {
117 return gatewayIp;
118 }
119
120 @Override
121 public String cidr() {
122 return cidr;
123 }
124
125 @Override
Jian Lifc0b8902021-01-12 16:34:49 +0900126 public Set<KubevirtHostRoute> hostRoutes() {
Jian Li034820d2021-01-15 16:58:48 +0900127 if (hostRoutes == null || hostRoutes.size() == 0) {
128 return ImmutableSet.of();
129 } else {
130 return ImmutableSet.copyOf(hostRoutes);
131 }
Jian Li8fe714d2021-01-11 02:35:06 +0900132 }
133
134 @Override
135 public KubevirtIpPool ipPool() {
136 return ipPool;
137 }
138
139 @Override
Jian Li4c35a262021-02-01 20:36:45 +0900140 public Set<IpAddress> dnses() {
141 if (dnses == null || dnses.size() == 0) {
142 return ImmutableSet.of();
143 } else {
144 return ImmutableSet.copyOf(dnses);
145 }
146 }
147
148 @Override
Jian Li556709c2021-02-03 17:54:28 +0900149 public String tenantBridgeName() {
150 if (type == VXLAN || type == GRE || type == GENEVE) {
151 return TENANT_BRIDGE_PREFIX + segmentIdHex(segmentId);
152 }
153 return null;
154 }
155
156 @Override
157 public DeviceId tenantDeviceId(String hostname) {
158 if (type == VXLAN || type == GRE || type == GENEVE) {
159 String dpid = genDpidFromName(tenantBridgeName() + "-" + hostname);
160 if (dpid != null) {
161 return DeviceId.deviceId(dpid);
162 }
163 }
164 return null;
165 }
166
167 @Override
Jian Li858ccd72021-02-04 17:25:01 +0900168 public PortNumber tunnelToTenantPort(DeviceId deviceId) {
169 String portName = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(segmentId);
170 Port port = port(deviceId, portName);
171 if (port == null) {
172 return null;
173 } else {
174 return port.number();
175 }
176 }
177
178 @Override
Jian Li8fe714d2021-01-11 02:35:06 +0900179 public boolean equals(Object o) {
180 if (this == o) {
181 return true;
182 }
183 if (o == null || getClass() != o.getClass()) {
184 return false;
185 }
186 DefaultKubevirtNetwork that = (DefaultKubevirtNetwork) o;
187 return networkId.equals(that.networkId) && type == that.type &&
188 name.equals(that.name) && mtu.equals(that.mtu) &&
189 gatewayIp.equals(that.gatewayIp) &&
Jian Lifc0b8902021-01-12 16:34:49 +0900190 cidr.equals(that.cidr) && hostRoutes.equals(that.hostRoutes) &&
Jian Li4c35a262021-02-01 20:36:45 +0900191 ipPool.equals(that.ipPool) &&
192 dnses.equals(that.dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900193 }
194
195 @Override
196 public int hashCode() {
197 return Objects.hash(networkId, type, name, mtu, segmentId, gatewayIp,
Jian Li4c35a262021-02-01 20:36:45 +0900198 cidr, hostRoutes, ipPool, dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900199 }
200
201 @Override
202 public String toString() {
203 return MoreObjects.toStringHelper(this)
204 .add("networkId", networkId)
205 .add("type", type)
206 .add("name", name)
207 .add("mtu", mtu)
208 .add("segmentId", segmentId)
209 .add("gatewayIp", gatewayIp)
210 .add("cidr", cidr)
Jian Lifc0b8902021-01-12 16:34:49 +0900211 .add("hostRouts", hostRoutes)
Jian Li8fe714d2021-01-11 02:35:06 +0900212 .add("ipPool", ipPool)
Jian Li4c35a262021-02-01 20:36:45 +0900213 .add("dnses", dnses)
Jian Li8fe714d2021-01-11 02:35:06 +0900214 .toString();
215 }
216
Jian Li858ccd72021-02-04 17:25:01 +0900217 private Port port(DeviceId deviceId, String portName) {
218 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
219 return deviceService.getPorts(deviceId).stream()
220 .filter(p -> p.isEnabled() &&
221 Objects.equals(p.annotations().value(PORT_NAME), portName))
222 .findAny().orElse(null);
223 }
224
Jian Li556709c2021-02-03 17:54:28 +0900225 private String segmentIdHex(String segIdStr) {
226 int segId = Integer.parseInt(segIdStr);
227 return String.format("%06x", segId).toLowerCase();
228 }
229
230 private String genDpidFromName(String name) {
231 if (name != null) {
232 String hexString = Integer.toHexString(name.hashCode());
233 return OF_PREFIX + Strings.padStart(hexString, 16, '0');
234 }
235
236 return null;
237 }
238
Jian Li8fe714d2021-01-11 02:35:06 +0900239 /**
240 * Returns new builder instance.
241 *
242 * @return kubevirt port builder
243 */
244 public static Builder builder() {
245 return new Builder();
246 }
247
248 public static final class Builder implements KubevirtNetwork.Builder {
249
250 private String networkId;
251 private Type type;
252 private String name;
253 private Integer mtu;
254 private String segmentId;
255 private IpAddress gatewayIp;
256 private String cidr;
257 private Set<KubevirtHostRoute> hostRouts;
258 private KubevirtIpPool ipPool;
Jian Li4c35a262021-02-01 20:36:45 +0900259 private Set<IpAddress> dnses;
Jian Li8fe714d2021-01-11 02:35:06 +0900260
261 @Override
262 public KubevirtNetwork build() {
263 checkArgument(networkId != null, NOT_NULL_MSG, "networkId");
264 checkArgument(type != null, NOT_NULL_MSG, "type");
265 checkArgument(name != null, NOT_NULL_MSG, "name");
266 checkArgument(mtu != null, NOT_NULL_MSG, "mtu");
267 checkArgument(gatewayIp != null, NOT_NULL_MSG, "gatewayIp");
268 checkArgument(cidr != null, NOT_NULL_MSG, "cidr");
269 checkArgument(ipPool != null, NOT_NULL_MSG, "ipPool");
270
271 if (type != FLAT) {
272 checkArgument(segmentId != null, NOT_NULL_MSG, "segmentId");
273 }
274
Jian Li4c35a262021-02-01 20:36:45 +0900275 if (dnses == null) {
276 dnses = new HashSet<>();
277 }
278
Jian Li8fe714d2021-01-11 02:35:06 +0900279 return new DefaultKubevirtNetwork(networkId, type, name, mtu, segmentId,
Jian Li4c35a262021-02-01 20:36:45 +0900280 gatewayIp, cidr, hostRouts, ipPool, dnses);
Jian Li8fe714d2021-01-11 02:35:06 +0900281 }
282
283 @Override
284 public Builder networkId(String networkId) {
285 this.networkId = networkId;
286 return this;
287 }
288
289 @Override
290 public Builder name(String name) {
291 this.name = name;
292 return this;
293 }
294
295 @Override
296 public Builder type(Type type) {
297 this.type = type;
298 return this;
299 }
300
301 @Override
302 public Builder mtu(Integer mtu) {
303 this.mtu = mtu;
304 return this;
305 }
306
307 @Override
308 public Builder segmentId(String segmentId) {
309 this.segmentId = segmentId;
310 return this;
311 }
312
313 @Override
314 public Builder gatewayIp(IpAddress ipAddress) {
315 this.gatewayIp = ipAddress;
316 return this;
317 }
318
319 @Override
320 public Builder cidr(String cidr) {
321 this.cidr = cidr;
322 return this;
323 }
324
325 @Override
326 public Builder ipPool(KubevirtIpPool ipPool) {
327 this.ipPool = ipPool;
328 return this;
329 }
330
331 @Override
332 public Builder hostRoutes(Set<KubevirtHostRoute> hostRoutes) {
333 this.hostRouts = hostRoutes;
334 return this;
335 }
Jian Li4c35a262021-02-01 20:36:45 +0900336
337 @Override
Jian Li1c10cf22021-03-05 01:32:04 +0900338 public Builder dnses(Set<IpAddress> dnses) {
Jian Li4c35a262021-02-01 20:36:45 +0900339 this.dnses = dnses;
340 return this;
341 }
Jian Li8fe714d2021-01-11 02:35:06 +0900342 }
343}