blob: ed086ae94439abf3541750cb04428f341dd12e88 [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) {
Daniel Park157947f2021-04-09 17:50:53 +0900341 return;
342 }
343
344 Ethernet ethernet = buildGarpPacket(kubevirtPort.macAddress(), floatingIp.floatingIp());
345 if (ethernet == null) {
346 return;
347 }
348
349 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
350 .setOutput(externalPatchPortNum(deviceService, electedGw)).build();
351
352 packetService.emit(new DefaultOutboundPacket(electedGw.intgBridge(), treatment,
353 ByteBuffer.wrap(ethernet.serialize())));
354 }
355
Daniel Parkf3136042021-03-10 07:49:11 +0900356 private class InternalRouterEventListener implements KubevirtRouterListener {
357 private boolean isRelevantHelper() {
358 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
359 }
360
Daniel Parkf3136042021-03-10 07:49:11 +0900361 @Override
362 public void event(KubevirtRouterEvent event) {
363 switch (event.type()) {
Daniel Parkf3136042021-03-10 07:49:11 +0900364 case KUBEVIRT_FLOATING_IP_ASSOCIATED:
365 eventExecutor.execute(() -> processFloatingIpAssociation(event.subject(),
366 event.floatingIp()));
367 break;
368 case KUBEVIRT_FLOATING_IP_DISASSOCIATED:
369 eventExecutor.execute(() -> processFloatingIpDisassociation(event.subject(),
370 event.floatingIp()));
371 break;
Daniel Park157947f2021-04-09 17:50:53 +0900372 case KUBEVIRT_GATEWAY_NODE_CHANGED:
373 eventExecutor.execute(() -> processRouterGatewayNodeChanged(event.subject(),
374 event.gateway()));
375 break;
Jian Li8f944d42021-03-23 00:43:29 +0900376 case KUBEVIRT_GATEWAY_NODE_ATTACHED:
377 eventExecutor.execute(() -> processGatewayNodeAttachment(event.subject(),
378 event.gateway()));
379 break;
380 case KUBEVIRT_GATEWAY_NODE_DETACHED:
381 eventExecutor.execute(() -> processGatewayNodeDetachment(event.subject(),
382 event.gateway()));
383 break;
Daniel Parkf3136042021-03-10 07:49:11 +0900384 default:
385 //do nothing
386 break;
387 }
388 }
389
Daniel Park157947f2021-04-09 17:50:53 +0900390 private void processRouterGatewayNodeChanged(KubevirtRouter router, String disAssociatedGateway) {
Daniel Parka5ba88d2021-05-28 15:46:46 +0900391 kubevirtRouterService.floatingIpsByRouter(router.name())
392 .forEach(fip -> {
Daniel Park157947f2021-04-09 17:50:53 +0900393 KubevirtNode newGw = kubevirtNodeService.node(router.electedGateway());
394 if (newGw == null) {
395 return;
396 }
Daniel Park157947f2021-04-09 17:50:53 +0900397 setFloatingIpRulesForFip(router, fip, newGw, true);
398 processGarpPacketForFloatingIp(fip, newGw);
Daniel Parka5ba88d2021-05-28 15:46:46 +0900399 KubevirtNode oldGw = kubevirtNodeService.node(disAssociatedGateway);
Daniel Park157947f2021-04-09 17:50:53 +0900400
Daniel Parka5ba88d2021-05-28 15:46:46 +0900401 if (oldGw == null) {
402 return;
403 }
404 setFloatingIpRulesForFip(router, fip, oldGw, false);
405 });
Daniel Park157947f2021-04-09 17:50:53 +0900406 }
407
Jian Li8f944d42021-03-23 00:43:29 +0900408 private void processGatewayNodeAttachment(KubevirtRouter router, String gatewayName) {
Daniel Parka5ba88d2021-05-28 15:46:46 +0900409 kubevirtRouterService.floatingIpsByRouter(router.name())
410 .forEach(fip -> {
411 KubevirtNode gw = kubevirtNodeService.node(gatewayName);
412 if (gw != null) {
413 setFloatingIpRulesForFip(router, fip, gw, true);
414 }
415 });
Jian Li8f944d42021-03-23 00:43:29 +0900416 }
417
418 private void processGatewayNodeDetachment(KubevirtRouter router, String gatewayName) {
Daniel Parka5ba88d2021-05-28 15:46:46 +0900419 kubevirtRouterService.floatingIpsByRouter(router.name())
420 .forEach(fip -> {
421 KubevirtNode gw = kubevirtNodeService.node(gatewayName);
422 if (gw != null) {
423 setFloatingIpRulesForFip(router, fip, gw, false);
424 }
425 });
Jian Li8f944d42021-03-23 00:43:29 +0900426 }
427
Daniel Parkf3136042021-03-10 07:49:11 +0900428 private void processFloatingIpAssociation(KubevirtRouter router, KubevirtFloatingIp floatingIp) {
Daniel Park157947f2021-04-09 17:50:53 +0900429 if (!isRelevantHelper() || router.electedGateway() == null) {
Daniel Parkf3136042021-03-10 07:49:11 +0900430 return;
431 }
Daniel Park157947f2021-04-09 17:50:53 +0900432
433 KubevirtNode electedGw = kubevirtNodeService.node(router.electedGateway());
434
435 if (electedGw == null) {
436 return;
437 }
438
439 processGarpPacketForFloatingIp(floatingIp, electedGw);
440 setFloatingIpRulesForFip(router, floatingIp, electedGw, true);
Daniel Parkf3136042021-03-10 07:49:11 +0900441 }
442
443 private void processFloatingIpDisassociation(KubevirtRouter router, KubevirtFloatingIp floatingIp) {
Daniel Park157947f2021-04-09 17:50:53 +0900444 if (!isRelevantHelper() || router.electedGateway() == null) {
Daniel Parkf3136042021-03-10 07:49:11 +0900445 return;
446 }
Daniel Park157947f2021-04-09 17:50:53 +0900447
448 KubevirtNode electedGw = kubevirtNodeService.node(router.electedGateway());
449
450 if (electedGw == null) {
451 return;
452 }
453 setFloatingIpRulesForFip(router, floatingIp, electedGw, false);
Daniel Parkf3136042021-03-10 07:49:11 +0900454 }
455 }
Jian Li394bef52021-05-27 18:53:45 +0900456
457 private class InternalNodeListener implements KubevirtNodeListener {
458 private boolean isRelevantHelper() {
459 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
460 }
461
462 @Override
463 public void event(KubevirtNodeEvent event) {
464 switch (event.type()) {
465 case KUBEVIRT_NODE_COMPLETE:
466 eventExecutor.execute(() -> processNodeCompletion(event.subject()));
467 break;
468 default:
469 break;
470 }
471 }
472
473 private void processNodeCompletion(KubevirtNode node) {
474 if (!isRelevantHelper()) {
475 return;
476 }
477
478 for (KubevirtFloatingIp fip : kubevirtRouterService.floatingIps()) {
479 KubevirtRouter router = kubevirtRouterService.router(fip.routerName());
480 if (router == null) {
481 log.warn("The router {} is not found", fip.routerName());
482 continue;
483 }
484
485 if (node.hostname().equals(router.electedGateway())) {
486 setFloatingIpRulesForFip(router, fip, node, true);
487 log.info("Configure floating IP {} on gateway {}",
488 fip.floatingIp().toString(), node.hostname());
489 }
490 }
491 }
492 }
Daniel Parkf3136042021-03-10 07:49:11 +0900493}