blob: 6617128d6bb042d959a8cdd15bada256646e292e [file] [log] [blame]
Jian Li556709c2021-02-03 17:54:28 +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.impl;
17
18import com.google.common.collect.Lists;
Jian Li0c656f02021-06-07 13:32:39 +090019import org.onlab.osgi.DefaultServiceDirectory;
Jian Li858ccd72021-02-04 17:25:01 +090020import org.onlab.packet.ARP;
21import org.onlab.packet.EthType;
Jian Li556709c2021-02-03 17:54:28 +090022import org.onlab.packet.Ethernet;
23import org.onlab.packet.IPv4;
Jian Li858ccd72021-02-04 17:25:01 +090024import org.onlab.packet.Ip4Address;
Jian Li556709c2021-02-03 17:54:28 +090025import org.onlab.packet.IpAddress;
Jian Li858ccd72021-02-04 17:25:01 +090026import org.onlab.packet.IpPrefix;
Daniel Park2884b232021-03-04 18:58:47 +090027import org.onlab.packet.MacAddress;
Jian Li556709c2021-02-03 17:54:28 +090028import org.onlab.packet.TpPort;
29import org.onlab.packet.UDP;
30import org.onosproject.cluster.ClusterService;
31import org.onosproject.cluster.LeadershipService;
32import org.onosproject.cluster.NodeId;
33import org.onosproject.core.ApplicationId;
34import org.onosproject.core.CoreService;
35import org.onosproject.kubevirtnetworking.api.KubevirtFlowRuleService;
36import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
Jian Lifc7e6cf2021-04-08 11:13:24 +090037import org.onosproject.kubevirtnetworking.api.KubevirtNetworkAdminService;
Jian Li556709c2021-02-03 17:54:28 +090038import org.onosproject.kubevirtnetworking.api.KubevirtNetworkEvent;
39import org.onosproject.kubevirtnetworking.api.KubevirtNetworkListener;
40import org.onosproject.kubevirtnetworking.api.KubevirtNetworkService;
Daniel Parkbabde9c2021-03-09 13:37:42 +090041import org.onosproject.kubevirtnetworking.api.KubevirtPort;
42import org.onosproject.kubevirtnetworking.api.KubevirtPortEvent;
43import org.onosproject.kubevirtnetworking.api.KubevirtPortListener;
44import org.onosproject.kubevirtnetworking.api.KubevirtPortService;
Daniel Park2884b232021-03-04 18:58:47 +090045import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
46import org.onosproject.kubevirtnetworking.api.KubevirtRouterAdminService;
47import org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent;
48import org.onosproject.kubevirtnetworking.api.KubevirtRouterListener;
Jian Li556709c2021-02-03 17:54:28 +090049import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
50import org.onosproject.kubevirtnode.api.KubevirtNode;
51import org.onosproject.kubevirtnode.api.KubevirtNodeEvent;
52import org.onosproject.kubevirtnode.api.KubevirtNodeListener;
53import org.onosproject.kubevirtnode.api.KubevirtNodeService;
54import org.onosproject.net.Device;
55import org.onosproject.net.DeviceId;
Jian Li0c656f02021-06-07 13:32:39 +090056import org.onosproject.net.Port;
Jian Li556709c2021-02-03 17:54:28 +090057import org.onosproject.net.PortNumber;
58import org.onosproject.net.behaviour.BridgeConfig;
59import org.onosproject.net.behaviour.BridgeDescription;
60import org.onosproject.net.behaviour.BridgeName;
61import org.onosproject.net.behaviour.ControllerInfo;
62import org.onosproject.net.behaviour.DefaultBridgeDescription;
63import org.onosproject.net.behaviour.DefaultPatchDescription;
64import org.onosproject.net.behaviour.InterfaceConfig;
65import org.onosproject.net.behaviour.PatchDescription;
66import org.onosproject.net.device.DeviceAdminService;
Jian Li0c656f02021-06-07 13:32:39 +090067import org.onosproject.net.device.DeviceService;
Daniel Parka8968802021-02-25 09:14:22 +090068import org.onosproject.net.driver.DriverService;
Jian Li556709c2021-02-03 17:54:28 +090069import org.onosproject.net.flow.DefaultTrafficSelector;
70import org.onosproject.net.flow.DefaultTrafficTreatment;
71import org.onosproject.net.flow.TrafficSelector;
72import org.onosproject.net.flow.TrafficTreatment;
73import org.osgi.service.component.annotations.Activate;
74import org.osgi.service.component.annotations.Component;
75import org.osgi.service.component.annotations.Deactivate;
76import org.osgi.service.component.annotations.Reference;
77import org.osgi.service.component.annotations.ReferenceCardinality;
78import org.slf4j.Logger;
79
80import java.util.List;
81import java.util.Objects;
Daniel Park2884b232021-03-04 18:58:47 +090082import java.util.Set;
Jian Li556709c2021-02-03 17:54:28 +090083import java.util.concurrent.ExecutorService;
84
Jian Li556709c2021-02-03 17:54:28 +090085import static java.util.concurrent.Executors.newSingleThreadExecutor;
Jian Li858ccd72021-02-04 17:25:01 +090086import static org.onlab.packet.ICMP.CODE_ECHO_REQEUST;
87import static org.onlab.packet.ICMP.TYPE_ECHO_REPLY;
88import static org.onlab.packet.ICMP.TYPE_ECHO_REQUEST;
Jian Li556709c2021-02-03 17:54:28 +090089import static org.onlab.util.Tools.groupedThreads;
Daniel Parkbabde9c2021-03-09 13:37:42 +090090import static org.onosproject.kubevirtnetworking.api.Constants.FORWARDING_TABLE;
Jian Lif89d9602021-04-27 19:05:49 +090091import static org.onosproject.kubevirtnetworking.api.Constants.GW_ENTRY_TABLE;
Jian Li556709c2021-02-03 17:54:28 +090092import static org.onosproject.kubevirtnetworking.api.Constants.KUBEVIRT_NETWORKING_APP_ID;
Jian Li8f944d42021-03-23 00:43:29 +090093import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_DEFAULT_RULE;
Jian Li858ccd72021-02-04 17:25:01 +090094import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
Jian Li556709c2021-02-03 17:54:28 +090095import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_DHCP_RULE;
Jian Li858ccd72021-02-04 17:25:01 +090096import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_FORWARDING_RULE;
97import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ICMP_RULE;
Daniel Parkbabde9c2021-03-09 13:37:42 +090098import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_INTERNAL_ROUTING_RULE;
Jian Li8f944d42021-03-23 00:43:29 +090099import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_IP_EGRESS_RULE;
100import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_IP_INGRESS_RULE;
Daniel Parkf3136042021-03-10 07:49:11 +0900101import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_TUNNEL_RULE;
Jian Li8f944d42021-03-23 00:43:29 +0900102import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ACL_EGRESS_TABLE;
103import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ACL_INGRESS_TABLE;
Jian Li858ccd72021-02-04 17:25:01 +0900104import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ARP_TABLE;
Jian Li556709c2021-02-03 17:54:28 +0900105import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_DHCP_TABLE;
106import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_FORWARDING_TABLE;
Jian Li858ccd72021-02-04 17:25:01 +0900107import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ICMP_TABLE;
Jian Li556709c2021-02-03 17:54:28 +0900108import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_INBOUND_TABLE;
Jian Li858ccd72021-02-04 17:25:01 +0900109import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_TO_TUNNEL_PREFIX;
Daniel Parkf3136042021-03-10 07:49:11 +0900110import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_DEFAULT_TABLE;
Jian Li858ccd72021-02-04 17:25:01 +0900111import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_TO_TENANT_PREFIX;
Daniel Park4cb120b2021-03-24 12:30:50 +0900112import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.FLAT;
113import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.VLAN;
Daniel Park2884b232021-03-04 18:58:47 +0900114import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.gatewayNodeForSpecifiedRouter;
Daniel Parkbabde9c2021-03-09 13:37:42 +0900115import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterForKubevirtNetwork;
116import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterForKubevirtPort;
Daniel Parkf3136042021-03-10 07:49:11 +0900117import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterMacAddress;
118import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.portNumber;
Jian Li94b6d162021-04-15 17:09:11 +0900119import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.resolveHostname;
Jian Li556709c2021-02-03 17:54:28 +0900120import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.segmentIdHex;
Daniel Parkf3136042021-03-10 07:49:11 +0900121import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.tunnelPort;
122import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.tunnelToTenantPort;
Jian Li0c656f02021-06-07 13:32:39 +0900123import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.waitFor;
Jian Li858ccd72021-02-04 17:25:01 +0900124import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.NXM_NX_IP_TTL;
125import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.NXM_OF_ICMP_TYPE;
Daniel Parkf3136042021-03-10 07:49:11 +0900126import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildExtension;
Jian Li858ccd72021-02-04 17:25:01 +0900127import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildLoadExtension;
128import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveArpShaToThaExtension;
129import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveArpSpaToTpaExtension;
130import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveEthSrcToDstExtension;
131import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveIpSrcToDstExtension;
Jian Li556709c2021-02-03 17:54:28 +0900132import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_BRIDGE;
Daniel Parkf3136042021-03-10 07:49:11 +0900133import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_TO_INTEGRATION;
Daniel Parka8968802021-02-25 09:14:22 +0900134import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
135import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.WORKER;
Jian Li0c656f02021-06-07 13:32:39 +0900136import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Jian Li556709c2021-02-03 17:54:28 +0900137import static org.slf4j.LoggerFactory.getLogger;
138
139/**
140 * Handles kubevirt network events.
141 */
142@Component(immediate = true)
143public class KubevirtNetworkHandler {
144 protected final Logger log = getLogger(getClass());
145 private static final String DEFAULT_OF_PROTO = "tcp";
146 private static final int DEFAULT_OFPORT = 6653;
147 private static final int DPID_BEGIN = 3;
Jian Li858ccd72021-02-04 17:25:01 +0900148 private static final int DEFAULT_TTL = 0xff;
Jian Li556709c2021-02-03 17:54:28 +0900149
150 @Reference(cardinality = ReferenceCardinality.MANDATORY)
151 protected CoreService coreService;
152
153 @Reference(cardinality = ReferenceCardinality.MANDATORY)
154 protected ClusterService clusterService;
155
156 @Reference(cardinality = ReferenceCardinality.MANDATORY)
157 protected LeadershipService leadershipService;
158
159 @Reference(cardinality = ReferenceCardinality.MANDATORY)
160 protected DeviceAdminService deviceService;
161
162 @Reference(cardinality = ReferenceCardinality.MANDATORY)
163 protected KubevirtApiConfigService apiConfigService;
164
165 @Reference(cardinality = ReferenceCardinality.MANDATORY)
166 protected KubevirtNodeService nodeService;
167
168 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Lifc7e6cf2021-04-08 11:13:24 +0900169 protected KubevirtNetworkAdminService networkService;
Jian Li556709c2021-02-03 17:54:28 +0900170
171 @Reference(cardinality = ReferenceCardinality.MANDATORY)
172 protected KubevirtFlowRuleService flowService;
173
Daniel Parka8968802021-02-25 09:14:22 +0900174 @Reference(cardinality = ReferenceCardinality.MANDATORY)
175 protected DriverService driverService;
176
Daniel Park2884b232021-03-04 18:58:47 +0900177 @Reference(cardinality = ReferenceCardinality.MANDATORY)
178 protected KubevirtRouterAdminService kubevirtRouterService;
179
Daniel Parkbabde9c2021-03-09 13:37:42 +0900180 @Reference(cardinality = ReferenceCardinality.MANDATORY)
181 protected KubevirtPortService kubevirtPortService;
182
183 @Reference(cardinality = ReferenceCardinality.MANDATORY)
184 protected KubevirtNetworkService kubevirtNetworkService;
185
186 @Reference(cardinality = ReferenceCardinality.MANDATORY)
187 protected KubevirtNodeService kubevirtNodeService;
188
Jian Li556709c2021-02-03 17:54:28 +0900189 private final KubevirtNetworkListener networkListener = new InternalNetworkEventListener();
190 private final KubevirtNodeListener nodeListener = new InternalNodeEventListener();
Daniel Parkbabde9c2021-03-09 13:37:42 +0900191 private final KubevirtPortListener portListener = new InternalKubevirtPortListener();
Jian Li556709c2021-02-03 17:54:28 +0900192
Daniel Park2884b232021-03-04 18:58:47 +0900193 private final InternalRouterEventListener kubevirtRouterlistener =
194 new InternalRouterEventListener();
195
Jian Li556709c2021-02-03 17:54:28 +0900196 private final ExecutorService eventExecutor = newSingleThreadExecutor(
197 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
198
199 private ApplicationId appId;
200 private NodeId localNodeId;
201
202 @Activate
203 protected void activate() {
204 appId = coreService.registerApplication(KUBEVIRT_NETWORKING_APP_ID);
205 localNodeId = clusterService.getLocalNode().id();
Jian Li556709c2021-02-03 17:54:28 +0900206 leadershipService.runForLeadership(appId.name());
207
Daniel Parkbabde9c2021-03-09 13:37:42 +0900208 networkService.addListener(networkListener);
209 nodeService.addListener(nodeListener);
210 kubevirtPortService.addListener(portListener);
Daniel Park2884b232021-03-04 18:58:47 +0900211 kubevirtRouterService.addListener(kubevirtRouterlistener);
212
Jian Li556709c2021-02-03 17:54:28 +0900213 log.info("Started");
214 }
215
216 @Deactivate
217 protected void deactivate() {
218 networkService.removeListener(networkListener);
219 nodeService.removeListener(nodeListener);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900220 kubevirtPortService.removeListener(portListener);
Daniel Park2884b232021-03-04 18:58:47 +0900221 kubevirtRouterService.removeListener(kubevirtRouterlistener);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900222 leadershipService.withdraw(appId.name());
Jian Li556709c2021-02-03 17:54:28 +0900223 eventExecutor.shutdown();
224
225 log.info("Stopped");
226 }
227
228 private void createBridge(KubevirtNode node, KubevirtNetwork network) {
229
Jian Li8f944d42021-03-23 00:43:29 +0900230 Device tenantBridge = deviceService.getDevice(network.tenantDeviceId(node.hostname()));
231 if (tenantBridge != null) {
232 log.warn("The tenant bridge {} already exists at node {}",
Jian Li556709c2021-02-03 17:54:28 +0900233 network.tenantBridgeName(), node.hostname());
Daniel Parkf3136042021-03-10 07:49:11 +0900234 setDefaultRulesForTenantNetwork(node, network);
Jian Li556709c2021-02-03 17:54:28 +0900235 return;
236 }
237
238 Device device = deviceService.getDevice(node.ovsdb());
239
Jian Li94b6d162021-04-15 17:09:11 +0900240 IpAddress serverIp;
241 String serviceFqdn = apiConfigService.apiConfig().serviceFqdn();
242 IpAddress serviceIp = null;
243
244 if (serviceFqdn != null) {
245 serviceIp = resolveHostname(serviceFqdn);
246 }
247
248 if (serviceIp != null) {
249 serverIp = serviceIp;
250 } else {
251 serverIp = apiConfigService.apiConfig().ipAddress();
252 }
253
Jian Li556709c2021-02-03 17:54:28 +0900254 ControllerInfo controlInfo =
255 new ControllerInfo(serverIp, DEFAULT_OFPORT, DEFAULT_OF_PROTO);
256 List<ControllerInfo> controllers = Lists.newArrayList(controlInfo);
257
258 String dpid = network.tenantDeviceId(
259 node.hostname()).toString().substring(DPID_BEGIN);
260
Jian Li0c656f02021-06-07 13:32:39 +0900261 // if the bridge is already available, we skip creating a new bridge
262 if (!deviceService.isAvailable(DeviceId.deviceId(dpid))) {
263 BridgeDescription.Builder builder = DefaultBridgeDescription.builder()
264 .name(network.tenantBridgeName())
265 .failMode(BridgeDescription.FailMode.SECURE)
266 .datapathId(dpid)
267 .disableInBand()
268 .controllers(controllers);
Jian Li556709c2021-02-03 17:54:28 +0900269
Jian Li0c656f02021-06-07 13:32:39 +0900270 BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
271 bridgeConfig.addBridge(builder.build());
272
273 waitFor(3);
274 }
Jian Li556709c2021-02-03 17:54:28 +0900275 }
276
277 private void removeBridge(KubevirtNode node, KubevirtNetwork network) {
278 Device device = deviceService.getDevice(node.ovsdb());
279
280 BridgeName bridgeName = BridgeName.bridgeName(network.tenantBridgeName());
281
282 BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
283 bridgeConfig.deleteBridge(bridgeName);
284 deviceService.removeDevice(network.tenantDeviceId(node.hostname()));
285 }
286
Daniel Parkf3136042021-03-10 07:49:11 +0900287 private void createPatchTenantInterface(KubevirtNode node, KubevirtNetwork network) {
Jian Li556709c2021-02-03 17:54:28 +0900288 Device device = deviceService.getDevice(node.ovsdb());
289
290 if (device == null || !device.is(InterfaceConfig.class)) {
291 log.error("Failed to create patch interface on {}", node.ovsdb());
292 return;
293 }
294
295 InterfaceConfig ifaceConfig = device.as(InterfaceConfig.class);
296
Jian Li858ccd72021-02-04 17:25:01 +0900297 String tenantToTunIntf =
298 TENANT_TO_TUNNEL_PREFIX + segmentIdHex(network.segmentId());
299 String tunToTenantIntf =
300 TUNNEL_TO_TENANT_PREFIX + segmentIdHex(network.segmentId());
Jian Li556709c2021-02-03 17:54:28 +0900301
Jian Li0c656f02021-06-07 13:32:39 +0900302 if (!hasPort(DeviceId.deviceId(network.tenantBridgeName()), tenantToTunIntf)) {
303 // tenant bridge -> tunnel bridge
304 PatchDescription brTenantTunPatchDesc =
305 DefaultPatchDescription.builder()
306 .deviceId(network.tenantBridgeName())
307 .ifaceName(tenantToTunIntf)
308 .peer(tunToTenantIntf)
309 .build();
Jian Li556709c2021-02-03 17:54:28 +0900310
Jian Li0c656f02021-06-07 13:32:39 +0900311 ifaceConfig.addPatchMode(tenantToTunIntf, brTenantTunPatchDesc);
Jian Li556709c2021-02-03 17:54:28 +0900312
Jian Li0c656f02021-06-07 13:32:39 +0900313 waitFor(1);
314 }
315
316 if (!hasPort(DeviceId.deviceId(TUNNEL_BRIDGE), tunToTenantIntf)) {
317 // tunnel bridge -> tenant bridge
318 PatchDescription brTunTenantPatchDesc =
319 DefaultPatchDescription.builder()
320 .deviceId(TUNNEL_BRIDGE)
321 .ifaceName(tunToTenantIntf)
322 .peer(tenantToTunIntf)
323 .build();
324 ifaceConfig.addPatchMode(tunToTenantIntf, brTunTenantPatchDesc);
325
326 waitFor(1);
327 }
Jian Li556709c2021-02-03 17:54:28 +0900328 }
329
Jian Liea1ead72021-05-28 11:00:07 +0900330 private void removeAllFlows(KubevirtNode node, KubevirtNetwork network) {
331 DeviceId deviceId = network.tenantDeviceId(node.hostname());
332 flowService.purgeRules(deviceId);
333 }
334
Jian Li556709c2021-02-03 17:54:28 +0900335 private void removePatchInterface(KubevirtNode node, KubevirtNetwork network) {
336 Device device = deviceService.getDevice(node.ovsdb());
337
338 if (device == null || !device.is(InterfaceConfig.class)) {
339 log.error("Failed to create patch interface on {}", node.ovsdb());
340 return;
341 }
342
343 InterfaceConfig ifaceConfig = device.as(InterfaceConfig.class);
344
Jian Li858ccd72021-02-04 17:25:01 +0900345 String tunToIntIntf = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(network.segmentId());
Jian Li556709c2021-02-03 17:54:28 +0900346
347 ifaceConfig.removePatchMode(tunToIntIntf);
348 }
349
Jian Li8f944d42021-03-23 00:43:29 +0900350 private void setGatewayArpRulesForTenantNetwork(KubevirtNode node,
351 KubevirtNetwork network) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900352
353 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
354 if (router == null) {
355 return;
356 }
357
358 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
359 if (electedGw == null) {
360 return;
361 }
362
Jian Li8f944d42021-03-23 00:43:29 +0900363 setGatewayArpRuleForTenantInternalNetwork(router, network, TENANT_ARP_TABLE,
364 electedGw.intgBridge(), network.tenantDeviceId(node.hostname()), true);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900365 }
366
Jian Li8f944d42021-03-23 00:43:29 +0900367 private void setGatewayIcmpRulesForTenantNetwork(KubevirtNode node,
368 KubevirtNetwork network) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900369 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
370 if (router == null) {
371 return;
372 }
373
374 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
375 if (electedGw == null) {
376 return;
377 }
378
Jian Li8f944d42021-03-23 00:43:29 +0900379 setGatewayIcmpRuleForTenantInternalNetwork(router, network, TENANT_ICMP_TABLE,
380 electedGw.intgBridge(), network.tenantDeviceId(node.hostname()), true);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900381 }
382
Jian Li8f944d42021-03-23 00:43:29 +0900383 private void setGatewayRuleToWorkerNodeWhenNodeCreated(KubevirtNode node,
384 KubevirtNetwork network) {
Daniel Parkf3136042021-03-10 07:49:11 +0900385 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
386 if (router == null) {
387 return;
388 }
Daniel Parkbabde9c2021-03-09 13:37:42 +0900389
Daniel Parkf3136042021-03-10 07:49:11 +0900390 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
391 if (electedGw == null) {
392 return;
393 }
394
Jian Li8f944d42021-03-23 00:43:29 +0900395 setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
396 electedGw.intgBridge(), node, true);
Daniel Parkf3136042021-03-10 07:49:11 +0900397 }
398
Jian Li8f944d42021-03-23 00:43:29 +0900399 private void setDefaultRulesForTenantNetwork(KubevirtNode node,
400 KubevirtNetwork network) {
Jian Li556709c2021-02-03 17:54:28 +0900401 DeviceId deviceId = network.tenantDeviceId(node.hostname());
402
403 while (!deviceService.isAvailable(deviceId)) {
404 log.warn("Device {} is not ready for installing rules", deviceId);
Jian Li0c656f02021-06-07 13:32:39 +0900405 waitFor(3);
Jian Li556709c2021-02-03 17:54:28 +0900406 }
407
408 flowService.connectTables(deviceId, TENANT_INBOUND_TABLE, TENANT_DHCP_TABLE);
Jian Li858ccd72021-02-04 17:25:01 +0900409 flowService.connectTables(deviceId, TENANT_DHCP_TABLE, TENANT_ARP_TABLE);
410 flowService.connectTables(deviceId, TENANT_ARP_TABLE, TENANT_ICMP_TABLE);
411 flowService.connectTables(deviceId, TENANT_ICMP_TABLE, TENANT_FORWARDING_TABLE);
Jian Li556709c2021-02-03 17:54:28 +0900412
Jian Li8f944d42021-03-23 00:43:29 +0900413 setArpRuleForTenantNetwork(deviceId, true);
Daniel Parkf3136042021-03-10 07:49:11 +0900414 setDhcpRuleForTenantNetwork(deviceId, true);
Jian Li556709c2021-02-03 17:54:28 +0900415 setForwardingRule(deviceId, true);
416
Jian Li8f944d42021-03-23 00:43:29 +0900417 // security group related rules
418 setTenantIngressTransitionRule(network, network.tenantDeviceId(node.hostname()), true);
Jian Lif89d9602021-04-27 19:05:49 +0900419 setTenantEgressTransitionRule(network.tenantDeviceId(node.hostname()), true);
Jian Li8f944d42021-03-23 00:43:29 +0900420
Jian Li556709c2021-02-03 17:54:28 +0900421 log.info("Install default flow rules for tenant bridge {}", network.tenantBridgeName());
422 }
423
Daniel Parkf3136042021-03-10 07:49:11 +0900424 private void setDhcpRuleForTenantNetwork(DeviceId deviceId, boolean install) {
Jian Li556709c2021-02-03 17:54:28 +0900425 TrafficSelector selector = DefaultTrafficSelector.builder()
426 .matchEthType(Ethernet.TYPE_IPV4)
427 .matchIPProtocol(IPv4.PROTOCOL_UDP)
428 .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
429 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
430 .build();
431
432 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
433 .punt()
434 .build();
435
436 flowService.setRule(
437 appId,
438 deviceId,
439 selector,
440 treatment,
441 PRIORITY_DHCP_RULE,
442 TENANT_DHCP_TABLE,
443 install);
444 }
445
Jian Li858ccd72021-02-04 17:25:01 +0900446 private void setForwardingRule(DeviceId deviceId, boolean install) {
Jian Li556709c2021-02-03 17:54:28 +0900447 TrafficSelector selector = DefaultTrafficSelector.builder().build();
448 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
449 .setOutput(PortNumber.NORMAL)
450 .build();
451
452 flowService.setRule(
453 appId,
454 deviceId,
455 selector,
456 treatment,
Jian Li858ccd72021-02-04 17:25:01 +0900457 PRIORITY_FORWARDING_RULE,
Jian Li556709c2021-02-03 17:54:28 +0900458 TENANT_FORWARDING_TABLE,
459 install);
460 }
461
Daniel Park2884b232021-03-04 18:58:47 +0900462 private void initGatewayNodeForInternalNetwork(KubevirtNetwork network,
463 KubevirtRouter router,
464 KubevirtNode electedGateway,
465 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900466 switch (network.type()) {
467 case VXLAN:
468 case GRE:
469 case GENEVE:
Jian Li8f944d42021-03-23 00:43:29 +0900470 setDefaultEgressRuleToGatewayNode(router, network,
471 electedGateway.intgBridge(), install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900472 kubevirtNodeService.completeNodes(WORKER).forEach(node -> {
Jian Li8f944d42021-03-23 00:43:29 +0900473 setGatewayArpRuleForTenantInternalNetwork(router, network,
474 TENANT_ARP_TABLE, electedGateway.intgBridge(),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900475 network.tenantDeviceId(node.hostname()), install);
Jian Li8f944d42021-03-23 00:43:29 +0900476 setGatewayIcmpRuleForTenantInternalNetwork(router, network,
477 TENANT_ICMP_TABLE, electedGateway.intgBridge(),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900478 network.tenantDeviceId(node.hostname()), install);
Jian Li517597a2021-03-22 11:04:52 +0900479 setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
Daniel Parkf3136042021-03-10 07:49:11 +0900480 electedGateway.intgBridge(), node, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900481 });
Daniel Park4cb120b2021-03-24 12:30:50 +0900482 setGatewayProviderInterNetworkRoutingWithinSameRouter(network, router, electedGateway, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900483 break;
484 case FLAT:
485 case VLAN:
Jian Li8f944d42021-03-23 00:43:29 +0900486 setGatewayArpRuleForProviderInternalNetwork(router, network,
Jian Lif89d9602021-04-27 19:05:49 +0900487 GW_ENTRY_TABLE, electedGateway.intgBridge(), install);
Jian Li8f944d42021-03-23 00:43:29 +0900488 setGatewayIcmpRuleForProviderInternalNetwork(router, network,
Jian Lif89d9602021-04-27 19:05:49 +0900489 GW_ENTRY_TABLE, electedGateway.intgBridge(), install);
Jian Li8f944d42021-03-23 00:43:29 +0900490 setGatewayProviderInterNetworkRoutingWithinSameRouter(network,
491 router, electedGateway, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900492 break;
493 default:
494 // do nothing
495 break;
496 }
Daniel Park2884b232021-03-04 18:58:47 +0900497 }
498
Jian Li517597a2021-03-22 11:04:52 +0900499 private void setDefaultGatewayRuleToWorkerNodeTunBridge(KubevirtRouter router,
500 KubevirtNetwork network,
501 DeviceId gwDeviceId,
502 KubevirtNode workerNode,
503 boolean install) {
Daniel Parkf3136042021-03-10 07:49:11 +0900504 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900505
Daniel Parkf3136042021-03-10 07:49:11 +0900506 if (routerMacAddress == null) {
507 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
508 "there's no br-int port for device {}", gwDeviceId);
509 return;
510 }
511
512 KubevirtNode gwNode = kubevirtNodeService.node(gwDeviceId);
513
514 if (gwNode == null) {
515 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
516 "there's no gateway node for device {}", gwDeviceId);
517 return;
518 }
519
520
521 PortNumber patchPortNumber = tunnelToTenantPort(workerNode, network);
522 if (patchPortNumber == null) {
523 return;
524 }
525
526 PortNumber tunnelPortNumber = tunnelPort(workerNode, network);
527 if (tunnelPortNumber == null) {
528 return;
529 }
530
531 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
532 .matchInPort(patchPortNumber)
533 .matchEthType(Ethernet.TYPE_IPV4)
534 .matchEthDst((routerMacAddress));
535
536 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
537 .setTunnelId(Long.parseLong(network.segmentId()))
538 .extension(buildExtension(
539 deviceService,
540 workerNode.tunBridge(),
541 gwNode.dataIp().getIp4Address()),
542 workerNode.tunBridge())
543 .setOutput(tunnelPortNumber);
544
545 flowService.setRule(
546 appId,
547 workerNode.tunBridge(),
548 sBuilder.build(),
549 tBuilder.build(),
550 PRIORITY_FORWARDING_RULE,
551 TUNNEL_DEFAULT_TABLE,
552 install);
553 }
554
Jian Li8f944d42021-03-23 00:43:29 +0900555 private void setTenantIngressTransitionRule(KubevirtNetwork network,
556 DeviceId deviceId, boolean install) {
557 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
558 sBuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort())
559 .matchInPort(network.tenantToTunnelPort(deviceId));
560
561 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
562 tBuilder.transition(TENANT_ACL_INGRESS_TABLE);
563
564 flowService.setRule(appId,
565 deviceId,
566 sBuilder.build(),
567 tBuilder.build(),
568 PRIORITY_IP_INGRESS_RULE,
569 TENANT_ICMP_TABLE,
570 install
571 );
572 }
573
Jian Lif89d9602021-04-27 19:05:49 +0900574 private void setTenantEgressTransitionRule(DeviceId deviceId, boolean install) {
Jian Li8f944d42021-03-23 00:43:29 +0900575 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
576 sBuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort());
577
578 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
579 tBuilder.transition(TENANT_ACL_EGRESS_TABLE);
580
581 flowService.setRule(appId,
582 deviceId,
583 sBuilder.build(),
584 tBuilder.build(),
585 PRIORITY_IP_EGRESS_RULE,
586 TENANT_ICMP_TABLE,
587 install
588 );
589 }
590
Daniel Parkf3136042021-03-10 07:49:11 +0900591 private void setDefaultEgressRuleToGatewayNode(KubevirtRouter router,
592 KubevirtNetwork network,
593 DeviceId gwDeviceId,
594 boolean install) {
595 MacAddress routerMacAddress = getRouterMacAddress(router);
596
597 if (routerMacAddress == null) {
598 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
599 "there's no br-int port for device {}", gwDeviceId);
600 return;
601 }
602
603 KubevirtNode gwNode = kubevirtNodeService.node(gwDeviceId);
604
605 if (gwNode == null) {
606 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
607 "there's no gateway node for device {}", gwDeviceId);
608 return;
609 }
610
611 PortNumber tunToIntPortNum = portNumber(gwNode.tunBridge(), TUNNEL_TO_INTEGRATION);
612
613 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
614 .matchTunnelId(Long.parseLong(network.segmentId()));
615
616 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
617 .setOutput(tunToIntPortNum);
618
619 flowService.setRule(
620 appId,
621 gwNode.tunBridge(),
622 sBuilder.build(),
623 tBuilder.build(),
624 PRIORITY_TUNNEL_RULE,
625 TUNNEL_DEFAULT_TABLE,
626 install);
627 }
628
629
630 private void setGatewayIcmpRuleForTenantInternalNetwork(KubevirtRouter router,
631 KubevirtNetwork network,
632 int tableNum,
633 DeviceId gwDeviceId,
634 DeviceId tenantDeviceId,
635 boolean install) {
636 MacAddress routerMacAddress = getRouterMacAddress(router);
637
638 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900639 log.warn("Setting gateway ICMP rule for internal network because " +
640 "there's no br-int port for device {}", gwDeviceId);
641 return;
642 }
643
644 Device device = deviceService.getDevice(tenantDeviceId);
645
646 if (device == null) {
647 log.warn("Setting gateway icmp rule for internal network because " +
648 "there's no tenant device for {} to install gateway arp rule",
649 tenantDeviceId);
650 return;
651 }
652
653
654 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
655 .matchEthType(Ethernet.TYPE_IPV4)
656 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
657 .matchIcmpType(TYPE_ECHO_REQUEST)
658 .matchIcmpCode(CODE_ECHO_REQEUST)
659 .matchIPDst(IpPrefix.valueOf(network.gatewayIp(), 32));
660
661 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
662 .extension(buildMoveEthSrcToDstExtension(device), device.id())
663 .extension(buildMoveIpSrcToDstExtension(device), device.id())
664 .extension(buildLoadExtension(device,
665 NXM_NX_IP_TTL, DEFAULT_TTL), device.id())
666 .extension(buildLoadExtension(device,
667 NXM_OF_ICMP_TYPE, TYPE_ECHO_REPLY), device.id())
668 .setIpSrc(network.gatewayIp())
Daniel Parkf3136042021-03-10 07:49:11 +0900669 .setEthSrc(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900670 .setOutput(PortNumber.IN_PORT);
671
672 flowService.setRule(
673 appId,
674 tenantDeviceId,
675 sBuilder.build(),
676 tBuilder.build(),
677 PRIORITY_ICMP_RULE,
678 tableNum,
679 install);
680 }
681
Jian Li8f944d42021-03-23 00:43:29 +0900682 private void setArpRuleForTenantNetwork(DeviceId tenantDeviceId,
683 boolean install) {
684 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
685 .matchEthType(EthType.EtherType.ARP.ethType().toShort());
686
687 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
688 .transition(TENANT_FORWARDING_TABLE);
689
690 flowService.setRule(
691 appId,
692 tenantDeviceId,
693 sBuilder.build(),
694 tBuilder.build(),
695 PRIORITY_ARP_DEFAULT_RULE,
696 TENANT_ARP_TABLE,
697 install
698 );
699 }
700
Daniel Parkf3136042021-03-10 07:49:11 +0900701 private void setGatewayArpRuleForTenantInternalNetwork(KubevirtRouter router,
702 KubevirtNetwork network,
703 int tableNum,
704 DeviceId gwDeviceId,
705 DeviceId tenantDeviceId,
706 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900707
Daniel Parkf3136042021-03-10 07:49:11 +0900708 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900709
Daniel Parkf3136042021-03-10 07:49:11 +0900710 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900711 log.warn("Setting gateway arp rule for internal network because " +
712 "there's no br-int port for device {}", gwDeviceId);
713 return;
714 }
715
716 Device device = deviceService.getDevice(tenantDeviceId);
717
718 if (device == null) {
719 log.warn("Setting gateway arp rule for internal network because " +
720 "there's no tenant device for {} to install gateway arp rule",
721 tenantDeviceId);
722 return;
723 }
724
725
726 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
727 sBuilder.matchEthType(EthType.EtherType.ARP.ethType().toShort())
728 .matchArpOp(ARP.OP_REQUEST)
729 .matchArpTpa(Ip4Address.valueOf(network.gatewayIp().toString()));
730
731 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
732 tBuilder.extension(buildMoveEthSrcToDstExtension(device), device.id())
733 .extension(buildMoveArpShaToThaExtension(device), device.id())
734 .extension(buildMoveArpSpaToTpaExtension(device), device.id())
735 .setArpOp(ARP.OP_REPLY)
Daniel Parkf3136042021-03-10 07:49:11 +0900736 .setArpSha(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900737 .setArpSpa(Ip4Address.valueOf(network.gatewayIp().toString()))
Daniel Parkf3136042021-03-10 07:49:11 +0900738 .setEthSrc(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900739 .setOutput(PortNumber.IN_PORT);
740
741 flowService.setRule(
742 appId,
743 device.id(),
744 sBuilder.build(),
745 tBuilder.build(),
746 PRIORITY_ARP_GATEWAY_RULE,
747 tableNum,
748 install
749 );
750 }
751
Daniel Parkf3136042021-03-10 07:49:11 +0900752 private void setGatewayProviderInterNetworkRoutingWithinSameRouter(
Daniel Parkbabde9c2021-03-09 13:37:42 +0900753 KubevirtNetwork network, KubevirtRouter router, KubevirtNode gatewayNode, boolean install) {
Daniel Park2884b232021-03-04 18:58:47 +0900754 router.internal().forEach(srcNetwork -> {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900755 if (srcNetwork.equals(network.networkId())
756 || kubevirtNetworkService.network(srcNetwork) == null) {
Daniel Park2884b232021-03-04 18:58:47 +0900757 return;
758 }
759
Daniel Parkbabde9c2021-03-09 13:37:42 +0900760 kubevirtPortService.ports(network.networkId()).forEach(port -> {
Daniel Parkf3136042021-03-10 07:49:11 +0900761 setGatewayInterNetworkRoutingFromNetworkToPort(router, kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900762 port, gatewayNode, install);
763 });
Daniel Park2884b232021-03-04 18:58:47 +0900764 });
765 }
766
Daniel Parkf3136042021-03-10 07:49:11 +0900767 private void setGatewayInterNetworkRoutingFromNetworkToPort(KubevirtRouter router,
768 KubevirtNetwork srcNetwork,
769 KubevirtPort dstPort,
770 KubevirtNode gatewayNode,
771 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900772 Device gwDevice = deviceService.getDevice(gatewayNode.intgBridge());
773
774 if (gwDevice == null) {
775 log.warn("Failed to set internal network routing rule because " +
776 "there's no device Id for device {}", gatewayNode.intgBridge());
777 return;
778 }
779
Daniel Parkf3136042021-03-10 07:49:11 +0900780 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900781
Daniel Parkf3136042021-03-10 07:49:11 +0900782 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900783 log.warn("Failed to set internal network routing rule because " +
784 "there's no br-int port for device {}", gatewayNode.intgBridge());
785 return;
786 }
787
Daniel Park4cb120b2021-03-24 12:30:50 +0900788 TrafficSelector.Builder sBuilder;
789 TrafficTreatment treatment;
Daniel Parkbabde9c2021-03-09 13:37:42 +0900790
Daniel Park4cb120b2021-03-24 12:30:50 +0900791 if (srcNetwork.type() == FLAT || srcNetwork.type() == VLAN) {
792 sBuilder = DefaultTrafficSelector.builder()
793 .matchEthType(Ethernet.TYPE_IPV4)
794 .matchEthDst(routerMacAddress)
795 .matchIPSrc(IpPrefix.valueOf(srcNetwork.cidr()))
796 .matchIPDst(IpPrefix.valueOf(dstPort.ipAddress(), 32));
Daniel Parkbabde9c2021-03-09 13:37:42 +0900797
Daniel Park4cb120b2021-03-24 12:30:50 +0900798 treatment = DefaultTrafficTreatment.builder()
799 .setEthSrc(routerMacAddress)
800 .setEthDst(dstPort.macAddress())
801 .transition(FORWARDING_TABLE)
802 .build();
803
804 flowService.setRule(
805 appId,
806 gwDevice.id(),
807 sBuilder.build(),
808 treatment,
809 PRIORITY_INTERNAL_ROUTING_RULE,
Jian Lif89d9602021-04-27 19:05:49 +0900810 GW_ENTRY_TABLE,
Daniel Park4cb120b2021-03-24 12:30:50 +0900811 install);
812 } else {
813 KubevirtNetwork dstNetwork = kubevirtNetworkService.network(dstPort.networkId());
814 if (dstNetwork == null) {
815 return;
816 }
817
818 KubevirtNode dstPortWorkerNode = kubevirtNodeService.node(dstPort.deviceId());
819 if (dstPortWorkerNode == null) {
820 return;
821 }
822
823 sBuilder = DefaultTrafficSelector.builder()
824 .matchEthType(Ethernet.TYPE_IPV4)
825 .matchEthDst(routerMacAddress)
826 .matchTunnelId(Long.parseLong(srcNetwork.segmentId()))
827 .matchIPSrc(IpPrefix.valueOf(srcNetwork.cidr()))
828 .matchIPDst(IpPrefix.valueOf(dstPort.ipAddress(), 32));
829
830 treatment = DefaultTrafficTreatment.builder()
831 .setTunnelId(Long.parseLong(dstNetwork.segmentId()))
832 .setEthSrc(routerMacAddress)
833 .setEthDst(dstPort.macAddress())
834 .extension(buildExtension(
835 deviceService,
836 gatewayNode.tunBridge(),
837 dstPortWorkerNode.dataIp().getIp4Address()),
838 gatewayNode.tunBridge())
839 .setOutput(PortNumber.IN_PORT)
840 .build();
841
842 flowService.setRule(
843 appId,
844 gatewayNode.tunBridge(),
845 sBuilder.build(),
846 treatment,
847 PRIORITY_INTERNAL_ROUTING_RULE,
848 TUNNEL_DEFAULT_TABLE,
849 install);
850 }
Daniel Parkbabde9c2021-03-09 13:37:42 +0900851 }
852
Daniel Parkf3136042021-03-10 07:49:11 +0900853 private void setGatewayArpRuleForProviderInternalNetwork(KubevirtRouter router, KubevirtNetwork network,
854 int tableNum, DeviceId gwDeviceId, boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900855
856
857 Device device = deviceService.getDevice(gwDeviceId);
Daniel Parkf3136042021-03-10 07:49:11 +0900858 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900859
Daniel Parkf3136042021-03-10 07:49:11 +0900860 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900861 log.warn("Setting gateway arp rule for internal network because " +
862 "there's no br-int port for device {}", gwDeviceId);
Daniel Park2884b232021-03-04 18:58:47 +0900863 return;
864 }
865
Jian Li858ccd72021-02-04 17:25:01 +0900866 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
867 sBuilder.matchEthType(EthType.EtherType.ARP.ethType().toShort())
868 .matchArpOp(ARP.OP_REQUEST)
869 .matchArpTpa(Ip4Address.valueOf(network.gatewayIp().toString()));
870
871 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
872 tBuilder.extension(buildMoveEthSrcToDstExtension(device), device.id())
873 .extension(buildMoveArpShaToThaExtension(device), device.id())
874 .extension(buildMoveArpSpaToTpaExtension(device), device.id())
875 .setArpOp(ARP.OP_REPLY)
Daniel Parkf3136042021-03-10 07:49:11 +0900876 .setArpSha(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900877 .setArpSpa(Ip4Address.valueOf(network.gatewayIp().toString()))
Daniel Parkf3136042021-03-10 07:49:11 +0900878 .setEthSrc(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900879 .setOutput(PortNumber.IN_PORT);
880
881 flowService.setRule(
882 appId,
883 device.id(),
884 sBuilder.build(),
885 tBuilder.build(),
886 PRIORITY_ARP_GATEWAY_RULE,
Daniel Parka8968802021-02-25 09:14:22 +0900887 tableNum,
Jian Li858ccd72021-02-04 17:25:01 +0900888 install
889 );
890 }
891
Daniel Park2884b232021-03-04 18:58:47 +0900892 /**
893 * Sends ICMP echo reply for the ICMP echo request from the kubevirt VM.
894 *
Daniel Parkf3136042021-03-10 07:49:11 +0900895 * @param router kubevirt router
Daniel Park2884b232021-03-04 18:58:47 +0900896 * @param network kubevirt network
897 * @param tableNum flow table number
898 * @param deviceId device id of the selected gateway for the network
899 * @param install install if true, remove otherwise
900 */
Daniel Parkf3136042021-03-10 07:49:11 +0900901 private void setGatewayIcmpRuleForProviderInternalNetwork(KubevirtRouter router, KubevirtNetwork network,
902 int tableNum, DeviceId deviceId, boolean install) {
903 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900904
Daniel Parkf3136042021-03-10 07:49:11 +0900905 if (routerMacAddress == null) {
Daniel Park2884b232021-03-04 18:58:47 +0900906 log.error("Setting gateway ICMP rule for internal network because " +
907 "there's no br-int port for device {}", deviceId);
908 return;
909 }
910
Jian Li858ccd72021-02-04 17:25:01 +0900911 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
912 .matchEthType(Ethernet.TYPE_IPV4)
913 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
914 .matchIcmpType(TYPE_ECHO_REQUEST)
915 .matchIcmpCode(CODE_ECHO_REQEUST)
916 .matchIPDst(IpPrefix.valueOf(network.gatewayIp(), 32));
917
918 Device device = deviceService.getDevice(deviceId);
919 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
920 .extension(buildMoveEthSrcToDstExtension(device), device.id())
921 .extension(buildMoveIpSrcToDstExtension(device), device.id())
922 .extension(buildLoadExtension(device,
923 NXM_NX_IP_TTL, DEFAULT_TTL), device.id())
924 .extension(buildLoadExtension(device,
925 NXM_OF_ICMP_TYPE, TYPE_ECHO_REPLY), device.id())
926 .setIpSrc(network.gatewayIp())
Daniel Parkf3136042021-03-10 07:49:11 +0900927 .setEthSrc(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900928 .setOutput(PortNumber.IN_PORT);
929
930 flowService.setRule(
931 appId,
932 deviceId,
933 sBuilder.build(),
934 tBuilder.build(),
935 PRIORITY_ICMP_RULE,
Daniel Parka8968802021-02-25 09:14:22 +0900936 tableNum,
Jian Li858ccd72021-02-04 17:25:01 +0900937 install);
938 }
939
Jian Li0c656f02021-06-07 13:32:39 +0900940 private boolean hasPort(DeviceId deviceId, String portName) {
941 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
942 Port port = deviceService.getPorts(deviceId).stream()
943 .filter(p -> p.isEnabled() &&
944 Objects.equals(p.annotations().value(PORT_NAME), portName))
945 .findAny().orElse(null);
946 return port != null;
947 }
948
Daniel Park2884b232021-03-04 18:58:47 +0900949 private class InternalRouterEventListener implements KubevirtRouterListener {
950 private boolean isRelevantHelper() {
951 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
Daniel Parka8968802021-02-25 09:14:22 +0900952 }
953
Daniel Park2884b232021-03-04 18:58:47 +0900954 @Override
955 public void event(KubevirtRouterEvent event) {
956 switch (event.type()) {
957 case KUBEVIRT_ROUTER_CREATED:
958 eventExecutor.execute(() -> processRouterCreation(event.subject()));
959 break;
960 case KUBEVIRT_ROUTER_REMOVED:
961 eventExecutor.execute(() -> processRouterDeletion(event.subject()));
962 break;
963 case KUBEVIRT_ROUTER_UPDATED:
964 eventExecutor.execute(() -> processRouterUpdate(event.subject()));
965 break;
966 case KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED:
967 eventExecutor.execute(() -> processRouterInternalNetworksAttached(event.subject(),
968 event.internal()));
969 break;
970 case KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED:
971 eventExecutor.execute(() -> processRouterInternalNetworksDetached(event.subject(),
972 event.internal()));
973 break;
974 case KUBEVIRT_GATEWAY_NODE_ATTACHED:
975 eventExecutor.execute(() -> processRouterGatewayNodeAttached(event.subject(),
976 event.gateway()));
977 break;
978 case KUBEVIRT_GATEWAY_NODE_DETACHED:
979 eventExecutor.execute(() -> processRouterGatewayNodeDetached(event.subject(),
980 event.gateway()));
981 break;
982 case KUBEVIRT_GATEWAY_NODE_CHANGED:
983 eventExecutor.execute(() -> processRouterGatewayNodeChanged(event.subject(),
984 event.gateway()));
985 break;
Daniel Parka8968802021-02-25 09:14:22 +0900986
Daniel Park2884b232021-03-04 18:58:47 +0900987 default:
988 //do nothing
989 break;
990 }
991 }
992
993 private void processRouterCreation(KubevirtRouter router) {
994 // When a router is created, we performs the election process to associate the router
995 // to the specific gateway. After the election, KubevirtNetwork handler installs bunch of rules
996 // to elected gateway node so that VMs associated to the router can ping to their gateway IP.
997 // SNAT and floating ip rule setup is out of this handler's scope and would be done with the other handlers
998 if (!isRelevantHelper()) {
999 return;
1000 }
1001 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1002 if (electedGw == null) {
1003 return;
1004 }
1005
1006 router.internal().forEach(networkName -> {
1007 KubevirtNetwork network = networkService.network(networkName);
1008
1009 if (network != null) {
1010 initGatewayNodeForInternalNetwork(network, router, electedGw, true);
1011 }
1012 });
1013 kubevirtRouterService.updateRouter(router.updatedElectedGateway(electedGw.hostname()));
1014 }
1015
1016 private void processRouterDeletion(KubevirtRouter router) {
1017 if (!isRelevantHelper()) {
1018 return;
1019 }
1020 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1021 if (electedGw == null) {
1022 return;
1023 }
1024
1025 router.internal().forEach(networkName -> {
1026 KubevirtNetwork network = networkService.network(networkName);
1027
1028 if (network != null) {
1029 initGatewayNodeForInternalNetwork(network, router, electedGw, false);
1030 }
1031 });
1032 }
1033
1034 private void processRouterUpdate(KubevirtRouter router) {
1035 if (!isRelevantHelper()) {
1036 return;
1037 }
1038 if (router.electedGateway() == null) {
1039 return;
1040 }
1041
1042 KubevirtNode electedGw = nodeService.node(router.electedGateway());
1043
1044 router.internal().forEach(networkName -> {
1045 KubevirtNetwork network = networkService.network(networkName);
1046
1047 if (network != null) {
1048 initGatewayNodeForInternalNetwork(network, router, electedGw, true);
1049 }
1050 });
1051 }
1052
1053 private void processRouterInternalNetworksAttached(KubevirtRouter router,
1054 Set<String> attachedInternalNetworks) {
1055 if (!isRelevantHelper()) {
1056 return;
1057 }
1058 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1059 if (electedGw == null) {
1060 return;
1061 }
1062
1063 attachedInternalNetworks.forEach(networkName -> {
1064 KubevirtNetwork network = networkService.network(networkName);
1065
1066 if (network != null) {
1067 initGatewayNodeForInternalNetwork(network, router, electedGw, true);
1068 }
1069 });
1070 }
1071
1072 private void processRouterInternalNetworksDetached(KubevirtRouter router,
1073 Set<String> detachedInternalNetworks) {
1074 if (!isRelevantHelper()) {
1075 return;
1076 }
1077 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1078 if (electedGw == null) {
1079 return;
1080 }
1081
1082 detachedInternalNetworks.forEach(networkName -> {
1083 KubevirtNetwork network = networkService.network(networkName);
1084
1085 if (network != null) {
1086 initGatewayNodeForInternalNetwork(network, router, electedGw, false);
1087 }
Daniel Park2884b232021-03-04 18:58:47 +09001088
Daniel Parkbabde9c2021-03-09 13:37:42 +09001089 removeDetachedInternalNetworkRules(network, router, electedGw);
1090 });
1091 }
1092
Jian Li8f944d42021-03-23 00:43:29 +09001093 private void removeDetachedInternalNetworkRules(KubevirtNetwork removedNetwork,
1094 KubevirtRouter router,
Daniel Parkbabde9c2021-03-09 13:37:42 +09001095 KubevirtNode electedGw) {
Daniel Parkf3136042021-03-10 07:49:11 +09001096 router.internal().stream().filter(networkId -> kubevirtNetworkService.network(networkId) != null)
1097 .forEach(networkId -> {
1098 kubevirtPortService.ports(networkId).forEach(kubevirtPort -> {
1099 setGatewayInterNetworkRoutingFromNetworkToPort(
1100 router, removedNetwork, kubevirtPort, electedGw, false);
1101 });
Daniel Parkbabde9c2021-03-09 13:37:42 +09001102 });
Daniel Park2884b232021-03-04 18:58:47 +09001103 }
1104
1105 private void processRouterGatewayNodeAttached(KubevirtRouter router,
1106 String associatedGateway) {
1107 if (!isRelevantHelper()) {
1108 return;
1109 }
1110
1111 KubevirtNode gatewayNode = nodeService.node(associatedGateway);
1112 if (gatewayNode == null) {
1113 return;
1114 }
1115
1116 router.internal().forEach(networkName -> {
1117 KubevirtNetwork network = networkService.network(networkName);
1118
1119 if (network != null) {
1120 initGatewayNodeForInternalNetwork(network, router, gatewayNode, true);
1121 }
1122 });
1123 }
1124
1125 private void processRouterGatewayNodeDetached(KubevirtRouter router,
1126 String disAssociatedGateway) {
1127 if (!isRelevantHelper()) {
1128 return;
1129 }
1130
1131 KubevirtNode gatewayNode = nodeService.node(disAssociatedGateway);
1132 if (gatewayNode == null) {
1133 return;
1134 }
1135
1136 router.internal().forEach(networkName -> {
1137 KubevirtNetwork network = networkService.network(networkName);
1138
1139 if (network != null) {
1140 initGatewayNodeForInternalNetwork(network, router, gatewayNode, false);
1141 }
1142 });
1143 }
1144
1145 private void processRouterGatewayNodeChanged(KubevirtRouter router,
1146 String disAssociatedGateway) {
1147 if (!isRelevantHelper()) {
1148 return;
1149 }
1150
1151 KubevirtNode oldGatewayNode = nodeService.node(disAssociatedGateway);
1152 if (oldGatewayNode == null) {
1153 return;
1154 }
1155
1156 router.internal().forEach(networkName -> {
1157 KubevirtNetwork network = networkService.network(networkName);
1158
1159 if (network != null) {
1160 initGatewayNodeForInternalNetwork(network, router, oldGatewayNode, false);
1161 }
1162 });
1163
1164 KubevirtNode newGatewayNode = nodeService.node(router.electedGateway());
1165 if (newGatewayNode == null) {
1166 return;
1167 }
1168
1169 router.internal().forEach(networkName -> {
1170 KubevirtNetwork network = networkService.network(networkName);
1171
1172 if (network != null) {
Daniel Parka5ba88d2021-05-28 15:46:46 +09001173 initGatewayNodeForInternalNetwork(network, router, newGatewayNode, true);
Daniel Park2884b232021-03-04 18:58:47 +09001174 }
1175 });
1176 }
Daniel Parka8968802021-02-25 09:14:22 +09001177 }
1178
Jian Li556709c2021-02-03 17:54:28 +09001179 private class InternalNetworkEventListener implements KubevirtNetworkListener {
1180
1181 private boolean isRelevantHelper() {
1182 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1183 }
1184
1185 @Override
1186 public void event(KubevirtNetworkEvent event) {
1187 switch (event.type()) {
1188 case KUBEVIRT_NETWORK_CREATED:
1189 eventExecutor.execute(() -> processNetworkCreation(event.subject()));
1190 break;
1191 case KUBEVIRT_NETWORK_REMOVED:
1192 eventExecutor.execute(() -> processNetworkRemoval(event.subject()));
1193 break;
1194 case KUBEVIRT_NETWORK_UPDATED:
1195 default:
1196 // do nothing
1197 break;
1198 }
1199 }
1200
1201 private void processNetworkCreation(KubevirtNetwork network) {
1202 if (!isRelevantHelper()) {
1203 return;
1204 }
1205
1206 switch (network.type()) {
1207 case VXLAN:
1208 case GRE:
1209 case GENEVE:
1210 initIntegrationTunnelBridge(network);
1211 break;
1212 case FLAT:
Jian Li2ce718e2021-02-17 20:42:15 +09001213 case VLAN:
Daniel Parka8968802021-02-25 09:14:22 +09001214 break;
Jian Li556709c2021-02-03 17:54:28 +09001215 default:
1216 // do nothing
1217 break;
1218 }
1219 }
1220
1221 private void processNetworkRemoval(KubevirtNetwork network) {
1222 if (!isRelevantHelper()) {
1223 return;
1224 }
1225
1226 switch (network.type()) {
1227 case VXLAN:
1228 case GRE:
1229 case GENEVE:
1230 purgeIntegrationTunnelBridge(network);
1231 break;
1232 case FLAT:
Jian Li2ce718e2021-02-17 20:42:15 +09001233 case VLAN:
Daniel Parka8968802021-02-25 09:14:22 +09001234 break;
Jian Li556709c2021-02-03 17:54:28 +09001235 default:
1236 // do nothing
1237 break;
1238 }
1239 }
1240
1241 private void initIntegrationTunnelBridge(KubevirtNetwork network) {
1242 if (network.segmentId() == null) {
1243 return;
1244 }
1245
Jian Li94b6d162021-04-15 17:09:11 +09001246 nodeService.completeNodes(WORKER).forEach(n -> {
Jian Li556709c2021-02-03 17:54:28 +09001247 createBridge(n, network);
Daniel Parkf3136042021-03-10 07:49:11 +09001248 createPatchTenantInterface(n, network);
1249 setDefaultRulesForTenantNetwork(n, network);
Jian Li556709c2021-02-03 17:54:28 +09001250 });
1251 }
1252
1253 private void purgeIntegrationTunnelBridge(KubevirtNetwork network) {
1254 if (network.segmentId() == null) {
1255 return;
1256 }
1257
Jian Li567b25c2021-05-27 15:17:59 +09001258 nodeService.completeNodes(WORKER).forEach(n -> {
Jian Liea1ead72021-05-28 11:00:07 +09001259 removeAllFlows(n, network);
Jian Li556709c2021-02-03 17:54:28 +09001260 removePatchInterface(n, network);
Jian Liea1ead72021-05-28 11:00:07 +09001261
Jian Li0c656f02021-06-07 13:32:39 +09001262 waitFor(5);
Jian Liea1ead72021-05-28 11:00:07 +09001263
Jian Li556709c2021-02-03 17:54:28 +09001264 removeBridge(n, network);
1265 });
1266 }
1267 }
1268
1269 private class InternalNodeEventListener implements KubevirtNodeListener {
1270
1271 private boolean isRelevantHelper() {
1272 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1273 }
1274
1275 @Override
1276 public void event(KubevirtNodeEvent event) {
1277 switch (event.type()) {
1278 case KUBEVIRT_NODE_COMPLETE:
1279 eventExecutor.execute(() -> processNodeCompletion(event.subject()));
1280 break;
Daniel Parka5ba88d2021-05-28 15:46:46 +09001281 case KUBEVIRT_NODE_INCOMPLETE:
Daniel Park2884b232021-03-04 18:58:47 +09001282 case KUBEVIRT_NODE_REMOVED:
1283 eventExecutor.execute(() -> processNodeDeletion(event.subject()));
1284 break;
Jian Li556709c2021-02-03 17:54:28 +09001285 case KUBEVIRT_NODE_UPDATED:
1286 default:
1287 // do nothing
1288 break;
1289 }
1290 }
1291
1292 private void processNodeCompletion(KubevirtNode node) {
1293 if (!isRelevantHelper()) {
1294 return;
1295 }
1296
Daniel Parka8968802021-02-25 09:14:22 +09001297 if (node.type().equals(WORKER)) {
1298 for (KubevirtNetwork network : networkService.networks()) {
1299 switch (network.type()) {
1300 case VXLAN:
1301 case GRE:
1302 case GENEVE:
1303 if (network.segmentId() == null) {
1304 continue;
1305 }
1306 createBridge(node, network);
Daniel Parkf3136042021-03-10 07:49:11 +09001307 createPatchTenantInterface(node, network);
1308 setDefaultRulesForTenantNetwork(node, network);
Jian Li8f944d42021-03-23 00:43:29 +09001309 setGatewayArpRulesForTenantNetwork(node, network);
1310 setGatewayIcmpRulesForTenantNetwork(node, network);
1311 setGatewayRuleToWorkerNodeWhenNodeCreated(node, network);
Daniel Parka8968802021-02-25 09:14:22 +09001312 break;
1313 case FLAT:
1314 case VLAN:
1315 default:
1316 // do nothing
1317 break;
1318 }
1319 }
1320 } else if (node.type().equals(GATEWAY)) {
Daniel Park2884b232021-03-04 18:58:47 +09001321 updateGatewayNodeForRouter();
Jian Li556709c2021-02-03 17:54:28 +09001322 }
1323 }
Daniel Park2884b232021-03-04 18:58:47 +09001324
1325 private void processNodeDeletion(KubevirtNode node) {
1326 if (!isRelevantHelper()) {
1327 return;
1328 }
Daniel Park2884b232021-03-04 18:58:47 +09001329 if (node.type().equals(GATEWAY)) {
Daniel Parka5ba88d2021-05-28 15:46:46 +09001330 kubevirtRouterService.routers()
1331 .stream()
1332 .filter(router -> router.electedGateway().equals(node.hostname()))
1333 .forEach(router -> {
1334 router.internal().forEach(networkName -> {
1335 KubevirtNetwork network = networkService.network(networkName);
1336
1337 if (network != null) {
1338 initGatewayNodeForInternalNetwork(network, router, node, false);
1339 }
1340 });
1341 });
Daniel Park2884b232021-03-04 18:58:47 +09001342 updateGatewayNodeForRouter();
Daniel Park2884b232021-03-04 18:58:47 +09001343 }
1344 }
1345
1346 private void updateGatewayNodeForRouter() {
1347 kubevirtRouterService.routers().forEach(router -> {
1348 KubevirtNode newGwNode = gatewayNodeForSpecifiedRouter(nodeService, router);
1349
1350 if (newGwNode == null) {
1351 return;
1352 }
1353 kubevirtRouterService.updateRouter(router.updatedElectedGateway(newGwNode.hostname()));
1354 });
1355 }
Jian Li556709c2021-02-03 17:54:28 +09001356 }
Daniel Parkbabde9c2021-03-09 13:37:42 +09001357
1358 private class InternalKubevirtPortListener implements KubevirtPortListener {
1359
1360 private boolean isRelevantHelper() {
1361 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1362 }
1363
1364 @Override
1365 public void event(KubevirtPortEvent event) {
1366 switch (event.type()) {
1367 case KUBEVIRT_PORT_CREATED:
1368 eventExecutor.execute(() -> processPortCreation(event.subject()));
1369 break;
1370 case KUBEVIRT_PORT_UPDATED:
1371 eventExecutor.execute(() -> processPortUpdate(event.subject()));
1372 break;
1373 case KUBEVIRT_PORT_REMOVED:
1374 eventExecutor.execute(() -> processPortDeletion(event.subject()));
1375 break;
1376 default:
1377 //do nothing
1378 break;
1379 }
1380 }
1381
1382 private void processPortCreation(KubevirtPort kubevirtPort) {
1383 if (!isRelevantHelper()) {
1384 return;
1385 }
1386
1387 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
1388 if (router == null) {
1389 return;
1390 }
1391
1392 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
1393
1394 if (gwNode != null) {
1395
1396 router.internal().forEach(srcNetwork -> {
1397 if (srcNetwork.equals(kubevirtPort.networkId())
1398 || kubevirtNetworkService.network(srcNetwork) == null) {
1399 return;
1400 }
Jian Li8f944d42021-03-23 00:43:29 +09001401 setGatewayInterNetworkRoutingFromNetworkToPort(router,
1402 kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +09001403 kubevirtPort, gwNode, true);
1404 });
1405 }
1406 }
1407
1408 private void processPortUpdate(KubevirtPort kubevirtPort) {
1409 if (!isRelevantHelper()) {
1410 return;
1411 }
1412
1413 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
1414 if (router == null) {
1415 return;
1416 }
1417
1418 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
1419
1420 if (gwNode != null) {
1421
1422 router.internal().forEach(srcNetwork -> {
1423 if (srcNetwork.equals(kubevirtPort.networkId())
1424 || kubevirtNetworkService.network(srcNetwork) == null) {
1425 return;
1426 }
Jian Li8f944d42021-03-23 00:43:29 +09001427 setGatewayInterNetworkRoutingFromNetworkToPort(router,
1428 kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +09001429 kubevirtPort, gwNode, true);
1430 });
1431 }
1432 }
1433
1434 private void processPortDeletion(KubevirtPort kubevirtPort) {
1435 if (!isRelevantHelper()) {
1436 return;
1437 }
1438
1439 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
1440 if (router == null) {
1441 return;
1442 }
1443
1444 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
1445
1446 if (gwNode != null) {
1447
1448 router.internal().forEach(srcNetwork -> {
1449 if (srcNetwork.equals(kubevirtPort.networkId())
1450 || kubevirtNetworkService.network(srcNetwork) == null) {
1451 return;
1452 }
Jian Li8f944d42021-03-23 00:43:29 +09001453 setGatewayInterNetworkRoutingFromNetworkToPort(router,
1454 kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +09001455 kubevirtPort, gwNode, false);
1456 });
1457 }
Daniel Parkbabde9c2021-03-09 13:37:42 +09001458 }
1459 }
Jian Li556709c2021-02-03 17:54:28 +09001460}