blob: cf8a877b55b2bb47c84052046ece580b8a8da8c7 [file] [log] [blame]
Daniel Parkf3136042021-03-10 07:49:11 +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 org.onlab.packet.ARP;
19import org.onlab.packet.EthType;
20import org.onlab.packet.Ethernet;
21import org.onlab.packet.IpPrefix;
22import org.onlab.packet.MacAddress;
23import org.onosproject.cluster.ClusterService;
24import org.onosproject.cluster.LeadershipService;
25import org.onosproject.cluster.NodeId;
26import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
28import org.onosproject.kubevirtnetworking.api.KubevirtFloatingIp;
29import org.onosproject.kubevirtnetworking.api.KubevirtFlowRuleService;
30import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
31import org.onosproject.kubevirtnetworking.api.KubevirtNetworkService;
32import org.onosproject.kubevirtnetworking.api.KubevirtPort;
33import org.onosproject.kubevirtnetworking.api.KubevirtPortService;
34import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
35import org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent;
36import org.onosproject.kubevirtnetworking.api.KubevirtRouterListener;
37import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
38import org.onosproject.kubevirtnetworking.util.RulePopulatorUtil;
39import org.onosproject.kubevirtnode.api.KubevirtNode;
Jian Li394bef52021-05-27 18:53:45 +090040import org.onosproject.kubevirtnode.api.KubevirtNodeEvent;
41import org.onosproject.kubevirtnode.api.KubevirtNodeListener;
Daniel Parkf3136042021-03-10 07:49:11 +090042import org.onosproject.kubevirtnode.api.KubevirtNodeService;
43import org.onosproject.net.Device;
44import org.onosproject.net.PortNumber;
45import org.onosproject.net.device.DeviceAdminService;
46import org.onosproject.net.driver.DriverService;
47import org.onosproject.net.flow.DefaultTrafficSelector;
48import org.onosproject.net.flow.DefaultTrafficTreatment;
49import org.onosproject.net.flow.TrafficSelector;
50import org.onosproject.net.flow.TrafficTreatment;
Daniel Park157947f2021-04-09 17:50:53 +090051import org.onosproject.net.packet.DefaultOutboundPacket;
52import org.onosproject.net.packet.PacketService;
Daniel Parkf3136042021-03-10 07:49:11 +090053import org.osgi.service.component.annotations.Activate;
54import org.osgi.service.component.annotations.Component;
55import org.osgi.service.component.annotations.Deactivate;
56import org.osgi.service.component.annotations.Reference;
57import org.osgi.service.component.annotations.ReferenceCardinality;
58import org.slf4j.Logger;
59
Daniel Park157947f2021-04-09 17:50:53 +090060import java.nio.ByteBuffer;
Daniel Parkf3136042021-03-10 07:49:11 +090061import java.util.Objects;
62import java.util.concurrent.ExecutorService;
63
64import static java.util.concurrent.Executors.newSingleThreadExecutor;
65import static org.onlab.util.Tools.groupedThreads;
66import static org.onosproject.kubevirtnetworking.api.Constants.FORWARDING_TABLE;
Jian Lif89d9602021-04-27 19:05:49 +090067import static org.onosproject.kubevirtnetworking.api.Constants.GW_ENTRY_TABLE;
Daniel Parkf3136042021-03-10 07:49:11 +090068import static org.onosproject.kubevirtnetworking.api.Constants.KUBEVIRT_NETWORKING_APP_ID;
Daniel Parkf3136042021-03-10 07:49:11 +090069import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
Daniel Park328fb602021-05-31 13:49:53 +090070import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_FLOATING_GATEWAY_TUN_BRIDGE_RULE;
Daniel Parkf3136042021-03-10 07:49:11 +090071import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_FLOATING_IP_RULE;
Daniel Parkf3136042021-03-10 07:49:11 +090072import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_DEFAULT_TABLE;
73import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GENEVE;
74import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GRE;
75import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.VXLAN;
Daniel Park157947f2021-04-09 17:50:53 +090076import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.buildGarpPacket;
Daniel Parkf3136042021-03-10 07:49:11 +090077import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.externalPatchPortNum;
Daniel Parkf3136042021-03-10 07:49:11 +090078import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterMacAddress;
79import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.tunnelPort;
80import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildExtension;
81import static org.slf4j.LoggerFactory.getLogger;
82
83/**
84 * Handles kubevirt floating ip.
85 */
86@Component(immediate = true)
87public class KubevirtFloatingIpHandler {
88 protected final Logger log = getLogger(getClass());
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY)
91 protected CoreService coreService;
92
93 @Reference(cardinality = ReferenceCardinality.MANDATORY)
94 protected ClusterService clusterService;
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY)
97 protected LeadershipService leadershipService;
98
99 @Reference(cardinality = ReferenceCardinality.MANDATORY)
100 protected DeviceAdminService deviceService;
101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Daniel Park157947f2021-04-09 17:50:53 +0900103 protected PacketService packetService;
104
105 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Daniel Parkf3136042021-03-10 07:49:11 +0900106 protected KubevirtPortService kubevirtPortService;
107
108 @Reference(cardinality = ReferenceCardinality.MANDATORY)
109 protected KubevirtNodeService kubevirtNodeService;
110
111 @Reference(cardinality = ReferenceCardinality.MANDATORY)
112 protected KubevirtNetworkService kubevirtNetworkService;
113
114 @Reference(cardinality = ReferenceCardinality.MANDATORY)
115 protected KubevirtFlowRuleService flowService;
116
117 @Reference(cardinality = ReferenceCardinality.MANDATORY)
118 protected DriverService driverService;
119
120 @Reference(cardinality = ReferenceCardinality.MANDATORY)
121 protected KubevirtRouterService kubevirtRouterService;
122
123 private final ExecutorService eventExecutor = newSingleThreadExecutor(
124 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
125
126 private ApplicationId appId;
127 private NodeId localNodeId;
128
Jian Li517597a2021-03-22 11:04:52 +0900129 private final InternalRouterEventListener kubevirtRouterListener =
Daniel Parkf3136042021-03-10 07:49:11 +0900130 new InternalRouterEventListener();
Jian Li394bef52021-05-27 18:53:45 +0900131 private final InternalNodeListener kubevirtNodeListener =
132 new InternalNodeListener();
Daniel Parkf3136042021-03-10 07:49:11 +0900133
134 @Activate
135 protected void activate() {
136 appId = coreService.registerApplication(KUBEVIRT_NETWORKING_APP_ID);
137 localNodeId = clusterService.getLocalNode().id();
138 leadershipService.runForLeadership(appId.name());
Jian Li517597a2021-03-22 11:04:52 +0900139 kubevirtRouterService.addListener(kubevirtRouterListener);
Jian Li394bef52021-05-27 18:53:45 +0900140 kubevirtNodeService.addListener(kubevirtNodeListener);
Daniel Parkf3136042021-03-10 07:49:11 +0900141
142 log.info("Started");
143 }
144
145 @Deactivate
146 protected void deactivate() {
147 leadershipService.withdraw(appId.name());
Jian Li517597a2021-03-22 11:04:52 +0900148 kubevirtRouterService.removeListener(kubevirtRouterListener);
Jian Li394bef52021-05-27 18:53:45 +0900149 kubevirtNodeService.removeListener(kubevirtNodeListener);
Daniel Parkf3136042021-03-10 07:49:11 +0900150
151 eventExecutor.shutdown();
152
153 log.info("Stopped");
154 }
155
Daniel Park157947f2021-04-09 17:50:53 +0900156 private void setFloatingIpRulesForFip(KubevirtRouter router,
157 KubevirtFloatingIp floatingIp,
158 KubevirtNode electedGw,
159 boolean install) {
Daniel Parkf3136042021-03-10 07:49:11 +0900160
161 KubevirtPort kubevirtPort = getKubevirtPort(floatingIp);
162 if (kubevirtPort == null) {
Daniel Parkf3136042021-03-10 07:49:11 +0900163 return;
164 }
165
166 KubevirtNetwork kubevirtNetwork = kubevirtNetworkService.network(kubevirtPort.networkId());
167 if (kubevirtNetwork.type() == VXLAN || kubevirtNetwork.type() == GENEVE || kubevirtNetwork.type() == GRE) {
Daniel Park328fb602021-05-31 13:49:53 +0900168 setFloatingIpDownstreamRulesToGatewayTunBridge(floatingIp,
169 electedGw, kubevirtNetwork, kubevirtPort, install);
Daniel Parkf3136042021-03-10 07:49:11 +0900170 }
171
Daniel Park157947f2021-04-09 17:50:53 +0900172 setFloatingIpArpResponseRules(router, floatingIp, kubevirtPort, electedGw, install);
173 setFloatingIpUpstreamRules(router, floatingIp, kubevirtPort, electedGw, install);
174 setFloatingIpDownstreamRules(router, floatingIp, kubevirtPort, electedGw, install);
Daniel Parkf3136042021-03-10 07:49:11 +0900175 }
176
177 private void setFloatingIpArpResponseRules(KubevirtRouter router,
178 KubevirtFloatingIp floatingIp,
179 KubevirtPort port,
Daniel Park157947f2021-04-09 17:50:53 +0900180 KubevirtNode electedGw,
Daniel Parkf3136042021-03-10 07:49:11 +0900181 boolean install) {
Daniel Parkf3136042021-03-10 07:49:11 +0900182 TrafficSelector selector = DefaultTrafficSelector.builder()
183 .matchInPort(externalPatchPortNum(deviceService, electedGw))
184 .matchEthType(EthType.EtherType.ARP.ethType().toShort())
185 .matchArpOp(ARP.OP_REQUEST)
186 .matchArpTpa(floatingIp.floatingIp().getIp4Address())
187 .build();
188
189 Device device = deviceService.getDevice(electedGw.intgBridge());
190
191 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
192 .extension(RulePopulatorUtil.buildMoveEthSrcToDstExtension(device), device.id())
193 .extension(RulePopulatorUtil.buildMoveArpShaToThaExtension(device), device.id())
194 .extension(RulePopulatorUtil.buildMoveArpSpaToTpaExtension(device), device.id())
195 .setArpOp(ARP.OP_REPLY)
196 .setEthSrc(port.macAddress())
197 .setArpSha(port.macAddress())
198 .setArpSpa(floatingIp.floatingIp().getIp4Address())
199 .setOutput(PortNumber.IN_PORT)
200 .build();
201
202 flowService.setRule(
203 appId,
204 electedGw.intgBridge(),
205 selector,
206 treatment,
207 PRIORITY_ARP_GATEWAY_RULE,
Jian Lif89d9602021-04-27 19:05:49 +0900208 GW_ENTRY_TABLE,
Daniel Parkf3136042021-03-10 07:49:11 +0900209 install);
210 }
Jian Li517597a2021-03-22 11:04:52 +0900211
Daniel Parkf3136042021-03-10 07:49:11 +0900212 private KubevirtPort getKubevirtPort(KubevirtFloatingIp floatingIp) {
213
214 return kubevirtPortService.ports().stream()
215 .filter(port -> port.ipAddress().equals(floatingIp.fixedIp()))
216 .findAny().orElse(null);
217 }
218
219 private void setFloatingIpUpstreamRules(KubevirtRouter router,
220 KubevirtFloatingIp floatingIp,
221 KubevirtPort port,
Daniel Park157947f2021-04-09 17:50:53 +0900222 KubevirtNode electedGw,
Daniel Parkf3136042021-03-10 07:49:11 +0900223 boolean install) {
224
Daniel Parkf3136042021-03-10 07:49:11 +0900225 MacAddress peerMacAddress = router.peerRouter().macAddress();
226
227 if (peerMacAddress == null) {
228 log.warn("Failed to install floating Ip rules for floating ip {} and router {}" +
229 "because there's no peer router mac address", floatingIp.floatingIp(),
230 router.name());
231 return;
232 }
233
234 MacAddress routerMacAddress = getRouterMacAddress(router);
235
236 TrafficSelector selector = DefaultTrafficSelector.builder()
237 .matchEthType(Ethernet.TYPE_IPV4)
238 .matchEthSrc(port.macAddress())
239 .matchEthDst(routerMacAddress)
240 .matchIPSrc(IpPrefix.valueOf(floatingIp.fixedIp(), 32))
241 .build();
242
243
244 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
245 .setEthDst(peerMacAddress)
246 .setEthSrc(port.macAddress())
247 .setIpSrc(floatingIp.floatingIp())
248 .setOutput(externalPatchPortNum(deviceService, electedGw))
249 .build();
250
251 flowService.setRule(
252 appId,
253 electedGw.intgBridge(),
254 selector,
255 treatment,
256 PRIORITY_FLOATING_IP_RULE,
Jian Lif89d9602021-04-27 19:05:49 +0900257 GW_ENTRY_TABLE,
Daniel Parkf3136042021-03-10 07:49:11 +0900258 install);
259 }
260
261 private void setFloatingIpDownstreamRules(KubevirtRouter router,
262 KubevirtFloatingIp floatingIp,
263 KubevirtPort port,
Daniel Park157947f2021-04-09 17:50:53 +0900264 KubevirtNode electedGw,
Daniel Parkf3136042021-03-10 07:49:11 +0900265 boolean install) {
Daniel Parkf3136042021-03-10 07:49:11 +0900266 MacAddress routerMacAddress = getRouterMacAddress(router);
267
268 TrafficSelector selector = DefaultTrafficSelector.builder()
269 .matchEthType(Ethernet.TYPE_IPV4)
270 .matchEthDst(port.macAddress())
271 .matchIPDst(IpPrefix.valueOf(floatingIp.floatingIp(), 32))
272 .build();
273
274 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
275 .setEthSrc(routerMacAddress)
276 .setEthDst(port.macAddress())
277 .setIpDst(floatingIp.fixedIp())
278 .transition(FORWARDING_TABLE)
279 .build();
280
281 flowService.setRule(
282 appId,
283 electedGw.intgBridge(),
284 selector,
285 treatment,
286 PRIORITY_FLOATING_IP_RULE,
Jian Lif89d9602021-04-27 19:05:49 +0900287 GW_ENTRY_TABLE,
Daniel Parkf3136042021-03-10 07:49:11 +0900288 install);
289 }
290
Daniel Park328fb602021-05-31 13:49:53 +0900291 private void setFloatingIpDownstreamRulesToGatewayTunBridge(KubevirtFloatingIp floatingIp,
292 KubevirtNode electedGw,
Daniel Parkf3136042021-03-10 07:49:11 +0900293 KubevirtNetwork network,
294 KubevirtPort port,
295 boolean install) {
Daniel Parkf3136042021-03-10 07:49:11 +0900296 KubevirtNode workerNode = kubevirtNodeService.node(port.deviceId());
297 if (workerNode == null) {
298 log.warn("Failed to install floating Ip rules for floating ip {} " +
299 "because fail to fine the worker node that the associated port is running on",
300 floatingIp.floatingIp());
Jian Li9793ec42021-03-19 15:03:32 +0900301 return;
Daniel Parkf3136042021-03-10 07:49:11 +0900302 }
303
304 PortNumber tunnelPortNumber = tunnelPort(electedGw, network);
305 if (tunnelPortNumber == null) {
306 return;
307 }
308
Daniel Parkf3136042021-03-10 07:49:11 +0900309 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
310 .matchEthType(Ethernet.TYPE_IPV4)
311 .matchIPDst(IpPrefix.valueOf(port.ipAddress(), 32))
312 .matchEthDst(port.macAddress());
313
314 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
315 .setTunnelId(Long.parseLong(network.segmentId()))
316 .extension(buildExtension(
317 deviceService,
318 electedGw.tunBridge(),
319 workerNode.dataIp().getIp4Address()),
320 electedGw.tunBridge())
321 .setOutput(tunnelPortNumber);
322
323 flowService.setRule(
324 appId,
325 electedGw.tunBridge(),
326 sBuilder.build(),
327 tBuilder.build(),
Daniel Park328fb602021-05-31 13:49:53 +0900328 PRIORITY_FLOATING_GATEWAY_TUN_BRIDGE_RULE,
Daniel Parkf3136042021-03-10 07:49:11 +0900329 TUNNEL_DEFAULT_TABLE,
330 install);
331 }
332
Daniel Park157947f2021-04-09 17:50:53 +0900333 private void processGarpPacketForFloatingIp(KubevirtFloatingIp floatingIp, KubevirtNode electedGw) {
334
335 if (floatingIp == null) {
336 return;
337 }
338
339 KubevirtPort kubevirtPort = getKubevirtPort(floatingIp);
340 if (kubevirtPort == null) {
341 log.warn("Failed to install floating Ip rules for floating ip {} " +
342 "because there's no kubevirt port associated to it", floatingIp.floatingIp());
343 return;
344 }
345
346 Ethernet ethernet = buildGarpPacket(kubevirtPort.macAddress(), floatingIp.floatingIp());
347 if (ethernet == null) {
348 return;
349 }
350
351 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
352 .setOutput(externalPatchPortNum(deviceService, electedGw)).build();
353
354 packetService.emit(new DefaultOutboundPacket(electedGw.intgBridge(), treatment,
355 ByteBuffer.wrap(ethernet.serialize())));
356 }
357
Daniel Parkf3136042021-03-10 07:49:11 +0900358 private class InternalRouterEventListener implements KubevirtRouterListener {
359 private boolean isRelevantHelper() {
360 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
361 }
362
Daniel Parkf3136042021-03-10 07:49:11 +0900363 @Override
364 public void event(KubevirtRouterEvent event) {
365 switch (event.type()) {
Daniel Parkf3136042021-03-10 07:49:11 +0900366 case KUBEVIRT_FLOATING_IP_ASSOCIATED:
367 eventExecutor.execute(() -> processFloatingIpAssociation(event.subject(),
368 event.floatingIp()));
369 break;
370 case KUBEVIRT_FLOATING_IP_DISASSOCIATED:
371 eventExecutor.execute(() -> processFloatingIpDisassociation(event.subject(),
372 event.floatingIp()));
373 break;
Daniel Park157947f2021-04-09 17:50:53 +0900374 case KUBEVIRT_GATEWAY_NODE_CHANGED:
375 eventExecutor.execute(() -> processRouterGatewayNodeChanged(event.subject(),
376 event.gateway()));
377 break;
Jian Li8f944d42021-03-23 00:43:29 +0900378 case KUBEVIRT_GATEWAY_NODE_ATTACHED:
379 eventExecutor.execute(() -> processGatewayNodeAttachment(event.subject(),
380 event.gateway()));
381 break;
382 case KUBEVIRT_GATEWAY_NODE_DETACHED:
383 eventExecutor.execute(() -> processGatewayNodeDetachment(event.subject(),
384 event.gateway()));
385 break;
Daniel Parkf3136042021-03-10 07:49:11 +0900386 default:
387 //do nothing
388 break;
389 }
390 }
391
Daniel Park157947f2021-04-09 17:50:53 +0900392 private void processRouterGatewayNodeChanged(KubevirtRouter router, String disAssociatedGateway) {
Daniel Parka5ba88d2021-05-28 15:46:46 +0900393 kubevirtRouterService.floatingIpsByRouter(router.name())
394 .forEach(fip -> {
Daniel Park157947f2021-04-09 17:50:53 +0900395 KubevirtNode newGw = kubevirtNodeService.node(router.electedGateway());
396 if (newGw == null) {
397 return;
398 }
Daniel Park157947f2021-04-09 17:50:53 +0900399 setFloatingIpRulesForFip(router, fip, newGw, true);
400 processGarpPacketForFloatingIp(fip, newGw);
Daniel Parka5ba88d2021-05-28 15:46:46 +0900401 KubevirtNode oldGw = kubevirtNodeService.node(disAssociatedGateway);
Daniel Park157947f2021-04-09 17:50:53 +0900402
Daniel Parka5ba88d2021-05-28 15:46:46 +0900403 if (oldGw == null) {
404 return;
405 }
406 setFloatingIpRulesForFip(router, fip, oldGw, false);
407 });
Daniel Park157947f2021-04-09 17:50:53 +0900408 }
409
Jian Li8f944d42021-03-23 00:43:29 +0900410 private void processGatewayNodeAttachment(KubevirtRouter router, String gatewayName) {
Daniel Parka5ba88d2021-05-28 15:46:46 +0900411 kubevirtRouterService.floatingIpsByRouter(router.name())
412 .forEach(fip -> {
413 KubevirtNode gw = kubevirtNodeService.node(gatewayName);
414 if (gw != null) {
415 setFloatingIpRulesForFip(router, fip, gw, true);
416 }
417 });
Jian Li8f944d42021-03-23 00:43:29 +0900418 }
419
420 private void processGatewayNodeDetachment(KubevirtRouter router, String gatewayName) {
Daniel Parka5ba88d2021-05-28 15:46:46 +0900421 kubevirtRouterService.floatingIpsByRouter(router.name())
422 .forEach(fip -> {
423 KubevirtNode gw = kubevirtNodeService.node(gatewayName);
424 if (gw != null) {
425 setFloatingIpRulesForFip(router, fip, gw, false);
426 }
427 });
Jian Li8f944d42021-03-23 00:43:29 +0900428 }
429
Daniel Parkf3136042021-03-10 07:49:11 +0900430 private void processFloatingIpAssociation(KubevirtRouter router, KubevirtFloatingIp floatingIp) {
Daniel Park157947f2021-04-09 17:50:53 +0900431 if (!isRelevantHelper() || router.electedGateway() == null) {
Daniel Parkf3136042021-03-10 07:49:11 +0900432 return;
433 }
Daniel Park157947f2021-04-09 17:50:53 +0900434
435 KubevirtNode electedGw = kubevirtNodeService.node(router.electedGateway());
436
437 if (electedGw == null) {
438 return;
439 }
440
441 processGarpPacketForFloatingIp(floatingIp, electedGw);
442 setFloatingIpRulesForFip(router, floatingIp, electedGw, true);
Daniel Parkf3136042021-03-10 07:49:11 +0900443 }
444
445 private void processFloatingIpDisassociation(KubevirtRouter router, KubevirtFloatingIp floatingIp) {
Daniel Park157947f2021-04-09 17:50:53 +0900446 if (!isRelevantHelper() || router.electedGateway() == null) {
Daniel Parkf3136042021-03-10 07:49:11 +0900447 return;
448 }
Daniel Park157947f2021-04-09 17:50:53 +0900449
450 KubevirtNode electedGw = kubevirtNodeService.node(router.electedGateway());
451
452 if (electedGw == null) {
453 return;
454 }
455 setFloatingIpRulesForFip(router, floatingIp, electedGw, false);
Daniel Parkf3136042021-03-10 07:49:11 +0900456 }
457 }
Jian Li394bef52021-05-27 18:53:45 +0900458
459 private class InternalNodeListener implements KubevirtNodeListener {
460 private boolean isRelevantHelper() {
461 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
462 }
463
464 @Override
465 public void event(KubevirtNodeEvent event) {
466 switch (event.type()) {
467 case KUBEVIRT_NODE_COMPLETE:
468 eventExecutor.execute(() -> processNodeCompletion(event.subject()));
469 break;
470 default:
471 break;
472 }
473 }
474
475 private void processNodeCompletion(KubevirtNode node) {
476 if (!isRelevantHelper()) {
477 return;
478 }
479
480 for (KubevirtFloatingIp fip : kubevirtRouterService.floatingIps()) {
481 KubevirtRouter router = kubevirtRouterService.router(fip.routerName());
482 if (router == null) {
483 log.warn("The router {} is not found", fip.routerName());
484 continue;
485 }
486
487 if (node.hostname().equals(router.electedGateway())) {
488 setFloatingIpRulesForFip(router, fip, node, true);
489 log.info("Configure floating IP {} on gateway {}",
490 fip.floatingIp().toString(), node.hostname());
491 }
492 }
493 }
494 }
Daniel Parkf3136042021-03-10 07:49:11 +0900495}