blob: 30cca2453524fc32efb10aaef26276164ff1ecc8 [file] [log] [blame]
Daniel Parkb9a22022021-03-04 18:58:47 +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.Ip4Address;
22import org.onlab.packet.IpAddress;
23import org.onlab.packet.IpPrefix;
24import org.onlab.packet.MacAddress;
25import org.onlab.packet.TpPort;
26import org.onosproject.cluster.ClusterService;
27import org.onosproject.cluster.LeadershipService;
28import org.onosproject.cluster.NodeId;
29import org.onosproject.core.ApplicationId;
30import org.onosproject.core.CoreService;
31import org.onosproject.kubevirtnetworking.api.KubevirtFlowRuleService;
32import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
33import org.onosproject.kubevirtnetworking.api.KubevirtNetworkEvent;
34import org.onosproject.kubevirtnetworking.api.KubevirtNetworkListener;
35import org.onosproject.kubevirtnetworking.api.KubevirtNetworkService;
36import org.onosproject.kubevirtnetworking.api.KubevirtPort;
37import org.onosproject.kubevirtnetworking.api.KubevirtPortEvent;
38import org.onosproject.kubevirtnetworking.api.KubevirtPortListener;
39import org.onosproject.kubevirtnetworking.api.KubevirtPortService;
40import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
41import org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent;
42import org.onosproject.kubevirtnetworking.api.KubevirtRouterListener;
43import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
44import org.onosproject.kubevirtnetworking.util.RulePopulatorUtil;
45import org.onosproject.kubevirtnode.api.KubevirtNode;
46import org.onosproject.kubevirtnode.api.KubevirtNodeService;
47import org.onosproject.net.Device;
48import org.onosproject.net.Port;
49import org.onosproject.net.PortNumber;
50import org.onosproject.net.device.DeviceAdminService;
51import org.onosproject.net.driver.DriverService;
52import org.onosproject.net.flow.DefaultTrafficSelector;
53import org.onosproject.net.flow.DefaultTrafficTreatment;
54import org.onosproject.net.flow.TrafficSelector;
55import org.onosproject.net.flow.TrafficTreatment;
56import org.onosproject.net.flow.instructions.ExtensionTreatment;
57import org.osgi.service.component.annotations.Activate;
58import org.osgi.service.component.annotations.Component;
59import org.osgi.service.component.annotations.Deactivate;
60import org.osgi.service.component.annotations.Reference;
61import org.osgi.service.component.annotations.ReferenceCardinality;
62import org.slf4j.Logger;
63
64import java.util.Objects;
65import java.util.Set;
66import java.util.concurrent.ExecutorService;
67
68import static java.util.concurrent.Executors.newSingleThreadExecutor;
69import static org.onlab.util.Tools.groupedThreads;
70import static org.onosproject.kubevirtnetworking.api.Constants.DEFAULT_GATEWAY_MAC;
71import static org.onosproject.kubevirtnetworking.api.Constants.FLAT_TABLE;
72import static org.onosproject.kubevirtnetworking.api.Constants.FORWARDING_TABLE;
73import static org.onosproject.kubevirtnetworking.api.Constants.KUBEVIRT_NETWORKING_APP_ID;
74import static org.onosproject.kubevirtnetworking.api.Constants.PRE_FLAT_TABLE;
75import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
76import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_STATEFUL_SNAT_RULE;
77import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.gatewayNodeForSpecifiedRouter;
78import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterSnatIpAddress;
79import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getbrIntMacAddress;
Daniel Parkcc8e7462021-03-09 13:37:42 +090080import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterForKubevirtPort;
Daniel Parkb9a22022021-03-04 18:58:47 +090081import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.CT_NAT_SRC_FLAG;
82import static org.onosproject.net.AnnotationKeys.PORT_NAME;
83import static org.slf4j.LoggerFactory.getLogger;
84
85/**
86 * Handles kubevirt routing snat.
87 */
88
89@Component(immediate = true)
90public class KubevirtRoutingSnatHandler {
91 protected final Logger log = getLogger(getClass());
92 private static final int DEFAULT_TTL = 0xff;
93
94 private static final int TP_PORT_MINIMUM_NUM = 1025;
95 private static final int TP_PORT_MAXIMUM_NUM = 65535;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY)
98 protected CoreService coreService;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY)
101 protected ClusterService clusterService;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY)
104 protected LeadershipService leadershipService;
105
106 @Reference(cardinality = ReferenceCardinality.MANDATORY)
107 protected DeviceAdminService deviceService;
108
109 @Reference(cardinality = ReferenceCardinality.MANDATORY)
110 protected KubevirtPortService kubevirtPortService;
111
112 @Reference(cardinality = ReferenceCardinality.MANDATORY)
113 protected KubevirtNodeService kubevirtNodeService;
114
115 @Reference(cardinality = ReferenceCardinality.MANDATORY)
116 protected KubevirtNetworkService kubevirtNetworkService;
117
118 @Reference(cardinality = ReferenceCardinality.MANDATORY)
119 protected KubevirtFlowRuleService flowService;
120
121 @Reference(cardinality = ReferenceCardinality.MANDATORY)
122 protected DriverService driverService;
123
124 @Reference(cardinality = ReferenceCardinality.MANDATORY)
125 protected KubevirtRouterService kubevirtRouterService;
126
127 private final ExecutorService eventExecutor = newSingleThreadExecutor(
128 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
129
130 private final InternalKubevirtPortListener kubevirtPortListener =
131 new InternalKubevirtPortListener();
132
133 private final InternalRouterEventListener kubevirtRouterlistener =
134 new InternalRouterEventListener();
135
136 private final InternalNetworkEventListener kubevirtNetworkEventListener =
137 new InternalNetworkEventListener();
138
139 private ApplicationId appId;
140 private NodeId localNodeId;
141
142 @Activate
143 protected void activate() {
144 appId = coreService.registerApplication(KUBEVIRT_NETWORKING_APP_ID);
145 localNodeId = clusterService.getLocalNode().id();
146 leadershipService.runForLeadership(appId.name());
147
148 kubevirtPortService.addListener(kubevirtPortListener);
149 kubevirtRouterService.addListener(kubevirtRouterlistener);
150 kubevirtNetworkService.addListener(kubevirtNetworkEventListener);
151
152 log.info("Started");
153 }
154
155 @Deactivate
156 protected void deactivate() {
157 leadershipService.withdraw(appId.name());
158 kubevirtPortService.removeListener(kubevirtPortListener);
159 kubevirtRouterService.removeListener(kubevirtRouterlistener);
160 kubevirtNetworkService.removeListener(kubevirtNetworkEventListener);
161
162 eventExecutor.shutdown();
163
164 log.info("Stopped");
165 }
166
167 private void initGatewayNodeSnatForRouter(KubevirtRouter router, boolean install) {
168 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
169
170 if (electedGw == null) {
171 log.warn("Fail to initialize gateway node snat for router {} " +
172 "there's no gateway assigned to it", router.name());
173 return;
174 }
175
176 String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
177
178 if (routerSnatIp == null) {
179 log.warn("Fail to initialize gateway node snat for router {} " +
180 "there's no gateway snat ip assigned to it", router.name());
181 return;
182 }
183
184 setArpResponseToPeerRouter(electedGw, Ip4Address.valueOf(routerSnatIp), install);
185 setStatefulSnatUpstreamRules(electedGw, router, Ip4Address.valueOf(routerSnatIp), install);
186 setStatefulSnatDownstreamRuleForRouter(router, electedGw, Ip4Address.valueOf(routerSnatIp), install);
187 }
188
189 private void setArpResponseToPeerRouter(KubevirtNode gatewayNode, Ip4Address ip4Address, boolean install) {
190
191 TrafficSelector selector = DefaultTrafficSelector.builder()
192 .matchInPort(externalPatchPortNum(gatewayNode))
193 .matchEthType(EthType.EtherType.ARP.ethType().toShort())
194 .matchArpOp(ARP.OP_REQUEST)
195 .matchArpTpa(ip4Address)
196 .build();
197
198 Device device = deviceService.getDevice(gatewayNode.intgBridge());
199
200 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
201 .extension(RulePopulatorUtil.buildMoveEthSrcToDstExtension(device), device.id())
202 .extension(RulePopulatorUtil.buildMoveArpShaToThaExtension(device), device.id())
203 .extension(RulePopulatorUtil.buildMoveArpSpaToTpaExtension(device), device.id())
204 .setArpOp(ARP.OP_REPLY)
205 .setEthSrc(DEFAULT_GATEWAY_MAC)
206 .setArpSha(DEFAULT_GATEWAY_MAC)
207 .setArpSpa(ip4Address)
208 .setOutput(PortNumber.IN_PORT)
209 .build();
210
211 flowService.setRule(
212 appId,
213 gatewayNode.intgBridge(),
214 selector,
215 treatment,
216 PRIORITY_ARP_GATEWAY_RULE,
217 PRE_FLAT_TABLE,
218 install);
219 }
220
221 private void setStatefulSnatUpstreamRules(KubevirtNode gatewayNode, KubevirtRouter router,
222 Ip4Address ip4Address, boolean install) {
223
224 MacAddress brIntMacAddress = getbrIntMacAddress(deviceService, gatewayNode.intgBridge());
225
226 TrafficSelector selector = DefaultTrafficSelector.builder()
227 .matchEthType(Ethernet.TYPE_IPV4)
228 .matchEthDst(brIntMacAddress)
229 .build();
230
231 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
232
233 ExtensionTreatment natTreatment = RulePopulatorUtil
234 .niciraConnTrackTreatmentBuilder(driverService, gatewayNode.intgBridge())
235 .commit(true)
236 .natFlag(CT_NAT_SRC_FLAG)
237 .natAction(true)
238 .natIp(ip4Address)
239 .natPortMin(TpPort.tpPort(TP_PORT_MINIMUM_NUM))
240 .natPortMax(TpPort.tpPort(TP_PORT_MAXIMUM_NUM))
241 .build();
242
243 tBuilder.extension(natTreatment, gatewayNode.intgBridge())
244 .setEthDst(router.peerRouter().macAddress())
245 .setEthSrc(DEFAULT_GATEWAY_MAC)
246 .setOutput(externalPatchPortNum(gatewayNode));
247
248 flowService.setRule(
249 appId,
250 gatewayNode.intgBridge(),
251 selector,
252 tBuilder.build(),
253 PRIORITY_STATEFUL_SNAT_RULE,
Daniel Parkcc8e7462021-03-09 13:37:42 +0900254 FLAT_TABLE,
Daniel Parkb9a22022021-03-04 18:58:47 +0900255 install);
256 }
257
258 private void setStatefulSnatDownStreamRuleForNetwork(KubevirtNode gatewayNode,
259 KubevirtRouter router,
260 KubevirtNetwork network,
261 boolean install) {
262 kubevirtPortService.ports(network.networkId()).forEach(kubevirtPort -> {
263 String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
264 if (routerSnatIp == null) {
265 return;
266 }
267 setStatefulSnatDownStreamRuleForKubevirtPort(gatewayNode, IpAddress.valueOf(routerSnatIp),
268 kubevirtPort, install);
269 });
270 }
271
272 private void setStatefulSnatDownStreamRuleForKubevirtPort(KubevirtNode gatewayNode,
273 IpAddress gatewaySnatIp,
274 KubevirtPort kubevirtPort,
275 boolean install) {
276 MacAddress brIntMacAddress = getbrIntMacAddress(deviceService, gatewayNode.intgBridge());
277
278 if (brIntMacAddress == null) {
279 log.error("Failed to set stateful snat downstream rule because " +
280 "there's no br-int port for device {}", gatewayNode.intgBridge());
281 return;
282 }
283
284 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
285 .matchEthType(Ethernet.TYPE_IPV4)
286 .matchIPDst(IpPrefix.valueOf(kubevirtPort.ipAddress(), 32));
287
288 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
289 .setEthDst(kubevirtPort.macAddress())
290 .transition(FORWARDING_TABLE)
291 .build();
292
293 flowService.setRule(
294 appId,
295 gatewayNode.intgBridge(),
296 sBuilder.build(),
297 treatment,
298 PRIORITY_STATEFUL_SNAT_RULE,
299 FLAT_TABLE,
300 install);
301 }
302
303 private void setStatefulSnatDownstreamRuleForRouter(KubevirtRouter router,
304 KubevirtNode gatewayNode,
305 IpAddress gatewaySnatIp,
306 boolean install) {
307
308 MacAddress brIntMacAddress = getbrIntMacAddress(deviceService, gatewayNode.intgBridge());
309
310 if (brIntMacAddress == null) {
311 log.error("Failed to set stateful snat downstream rule because " +
312 "there's no br-int port for device {}", gatewayNode.intgBridge());
313 return;
314 }
315
316 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
317 .matchEthType(Ethernet.TYPE_IPV4)
318 .matchIPDst(IpPrefix.valueOf(gatewaySnatIp, 32));
319
320 ExtensionTreatment natTreatment = RulePopulatorUtil
321 .niciraConnTrackTreatmentBuilder(driverService, gatewayNode.intgBridge())
322 .commit(false)
323 .natAction(true)
Daniel Parkcc8e7462021-03-09 13:37:42 +0900324 .table((short) FLAT_TABLE)
Daniel Parkb9a22022021-03-04 18:58:47 +0900325 .build();
326
327 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
328 .setEthSrc(brIntMacAddress)
329 .extension(natTreatment, gatewayNode.intgBridge())
330 .build();
331
332 flowService.setRule(
333 appId,
334 gatewayNode.intgBridge(),
335 sBuilder.build(),
336 treatment,
337 PRIORITY_STATEFUL_SNAT_RULE,
Daniel Parkcc8e7462021-03-09 13:37:42 +0900338 FLAT_TABLE,
Daniel Parkb9a22022021-03-04 18:58:47 +0900339 install);
340
341 router.internal().forEach(networkName -> {
342 KubevirtNetwork network = kubevirtNetworkService.network(networkName);
343
344 if (network != null) {
345 setStatefulSnatDownStreamRuleForNetwork(gatewayNode, router, network, install);
346 }
347 });
348 }
349
350 private PortNumber externalPatchPortNum(KubevirtNode gatewayNode) {
351 Port port = deviceService.getPorts(gatewayNode.intgBridge()).stream()
352 .filter(p -> p.isEnabled() &&
353 Objects.equals(p.annotations().value(PORT_NAME), "int-to-gateway"))
354 .findAny().orElse(null);
355
356 return port != null ? port.number() : null;
357 }
358
359 private class InternalRouterEventListener implements KubevirtRouterListener {
360 private boolean isRelevantHelper() {
361 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
362 }
363
364 @Override
365 public void event(KubevirtRouterEvent event) {
366 switch (event.type()) {
367 case KUBEVIRT_ROUTER_CREATED:
368 eventExecutor.execute(() -> processRouterCreation(event.subject()));
369 break;
370 case KUBEVIRT_ROUTER_REMOVED:
371 eventExecutor.execute(() -> processRouterDeletion(event.subject()));
372 break;
373 case KUBEVIRT_ROUTER_UPDATED:
374 eventExecutor.execute(() -> processRouterUpdate(event.subject()));
375 break;
376 case KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED:
377 eventExecutor.execute(() -> processRouterInternalNetworksAttached(event.subject(),
378 event.internal()));
379 break;
380 case KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED:
381 eventExecutor.execute(() -> processRouterInternalNetworksDetached(event.subject(),
382 event.internal()));
383 break;
384 default:
385 //do nothing
386 break;
387 }
388 }
389 private void processRouterInternalNetworksAttached(KubevirtRouter router,
390 Set<String> attachedInternalNetworks) {
391 if (!isRelevantHelper()) {
392 return;
393 }
394
395 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
396 if (gwNode == null) {
397 return;
398 }
399
400 attachedInternalNetworks.forEach(networkId -> {
401 kubevirtPortService.ports(networkId).forEach(kubevirtPort -> {
402 String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
403 if (routerSnatIp == null) {
404 return;
405 }
406 setStatefulSnatDownStreamRuleForKubevirtPort(gwNode, IpAddress.valueOf(routerSnatIp),
407 kubevirtPort, true);
408 });
409 });
410 }
411
412 private void processRouterInternalNetworksDetached(KubevirtRouter router,
413 Set<String> detachedInternalNetworks) {
414 if (!isRelevantHelper()) {
415 return;
416 }
417
418 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
419 if (gwNode == null) {
420 return;
421 }
422
423 detachedInternalNetworks.forEach(networkId -> {
424 kubevirtPortService.ports(networkId).forEach(kubevirtPort -> {
425 String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
426 if (routerSnatIp == null) {
427 log.info("snatIp is null");
428 return;
429 }
430 setStatefulSnatDownStreamRuleForKubevirtPort(gwNode, IpAddress.valueOf(routerSnatIp),
431 kubevirtPort, false);
432 });
433 });
434 }
435 private void processRouterCreation(KubevirtRouter router) {
436 if (!isRelevantHelper()) {
437 return;
438 }
439 if (router.enableSnat() && !router.external().isEmpty() && router.peerRouter() != null) {
440 initGatewayNodeSnatForRouter(router, true);
441 }
442 }
443
444 private void processRouterDeletion(KubevirtRouter router) {
445 if (!isRelevantHelper()) {
446 return;
447 }
448 if (router.enableSnat() && !router.external().isEmpty() && router.peerRouter() != null) {
449 initGatewayNodeSnatForRouter(router, false);
450 }
451 }
452
453 private void processRouterUpdate(KubevirtRouter router) {
454 if (!isRelevantHelper()) {
455 return;
456 }
457 if (router.enableSnat() && !router.external().isEmpty() && router.peerRouter() != null) {
458 initGatewayNodeSnatForRouter(router, true);
459 }
460 }
461 }
462
463 private class InternalNetworkEventListener implements KubevirtNetworkListener {
464
465 private boolean isRelevantHelper() {
466 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
467 }
468
469 @Override
470 public void event(KubevirtNetworkEvent event) {
471 switch (event.type()) {
472 case KUBEVIRT_NETWORK_CREATED:
473 eventExecutor.execute(() -> processNetworkCreation(event.subject()));
474 break;
475 case KUBEVIRT_NETWORK_REMOVED:
476 eventExecutor.execute(() -> processNetworkRemoval(event.subject()));
477 break;
478 case KUBEVIRT_NETWORK_UPDATED:
479 default:
480 // do nothing
481 break;
482 }
483 }
484
485 private void processNetworkCreation(KubevirtNetwork network) {
486 if (!isRelevantHelper()) {
487 return;
488 }
489
490 switch (network.type()) {
491 case VXLAN:
492 case GRE:
493 case GENEVE:
494 break;
495 case FLAT:
496 case VLAN:
497 break;
498 default:
499 // do nothing
500 break;
501 }
502 }
503
504 private void processNetworkRemoval(KubevirtNetwork network) {
505 if (!isRelevantHelper()) {
506 return;
507 }
508
509 switch (network.type()) {
510 case VXLAN:
511 case GRE:
512 case GENEVE:
513 break;
514 case FLAT:
515 case VLAN:
516 break;
517 default:
518 // do nothing
519 break;
520 }
521 }
522 }
523
524 private class InternalKubevirtPortListener implements KubevirtPortListener {
525
526 private boolean isRelevantHelper() {
527 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
528 }
529
530 @Override
531 public void event(KubevirtPortEvent event) {
532 switch (event.type()) {
533 case KUBEVIRT_PORT_CREATED:
534 eventExecutor.execute(() -> processPortCreation(event.subject()));
535 break;
536 case KUBEVIRT_PORT_UPDATED:
537 eventExecutor.execute(() -> processPortUpdate(event.subject()));
538 break;
539 case KUBEVIRT_PORT_REMOVED:
540 eventExecutor.execute(() -> processPortDeletion(event.subject()));
541 break;
542 default:
543 //do nothing
544 break;
545 }
546 }
547
548 private void processPortCreation(KubevirtPort kubevirtPort) {
549 if (!isRelevantHelper()) {
550 return;
551 }
552
Daniel Parkcc8e7462021-03-09 13:37:42 +0900553 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
Daniel Parkb9a22022021-03-04 18:58:47 +0900554 if (router == null) {
555 return;
556 }
557
558 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
559
560 if (gwNode != null) {
561 IpAddress gatewaySnatIp = getRouterSnatIpAddress(kubevirtRouterService, kubevirtPort.networkId());
562 if (gatewaySnatIp == null) {
563 return;
564 }
565 setStatefulSnatDownStreamRuleForKubevirtPort(gwNode, gatewaySnatIp, kubevirtPort, true);
566 }
567 }
568
569 private void processPortUpdate(KubevirtPort kubevirtPort) {
570 if (!isRelevantHelper()) {
571 return;
572 }
573
Daniel Parkcc8e7462021-03-09 13:37:42 +0900574 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
Daniel Parkb9a22022021-03-04 18:58:47 +0900575 if (router == null) {
576 return;
577 }
578
579 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
580
581 if (gwNode != null) {
582 IpAddress gatewaySnatIp = getRouterSnatIpAddress(kubevirtRouterService, kubevirtPort.networkId());
583 if (gatewaySnatIp == null) {
584 return;
585 }
586 setStatefulSnatDownStreamRuleForKubevirtPort(gwNode, gatewaySnatIp, kubevirtPort, true);
587 }
588 }
589
590 private void processPortDeletion(KubevirtPort kubevirtPort) {
591 if (!isRelevantHelper()) {
592 return;
593 }
594
Daniel Parkcc8e7462021-03-09 13:37:42 +0900595 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
Daniel Parkb9a22022021-03-04 18:58:47 +0900596 if (router == null) {
597 return;
598 }
599
600 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
601
602 if (gwNode != null) {
603 IpAddress gatewaySnatIp = getRouterSnatIpAddress(kubevirtRouterService, kubevirtPort.networkId());
604 if (gatewaySnatIp == null) {
605 return;
606 }
607 setStatefulSnatDownStreamRuleForKubevirtPort(gwNode, gatewaySnatIp, kubevirtPort, false);
608 }
609 }
Daniel Parkb9a22022021-03-04 18:58:47 +0900610 }
611}