blob: b82998047fd2721deb846c0b4f7d025d74176bc0 [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 Li858ccd72021-02-04 17:25:01 +090019import org.onlab.packet.ARP;
20import org.onlab.packet.EthType;
Jian Li556709c2021-02-03 17:54:28 +090021import org.onlab.packet.Ethernet;
22import org.onlab.packet.IPv4;
Jian Li858ccd72021-02-04 17:25:01 +090023import org.onlab.packet.Ip4Address;
Jian Li556709c2021-02-03 17:54:28 +090024import org.onlab.packet.IpAddress;
Jian Li858ccd72021-02-04 17:25:01 +090025import org.onlab.packet.IpPrefix;
Daniel Park2884b232021-03-04 18:58:47 +090026import org.onlab.packet.MacAddress;
Jian Li556709c2021-02-03 17:54:28 +090027import org.onlab.packet.TpPort;
28import org.onlab.packet.UDP;
29import org.onosproject.cluster.ClusterService;
30import org.onosproject.cluster.LeadershipService;
31import org.onosproject.cluster.NodeId;
32import org.onosproject.core.ApplicationId;
33import org.onosproject.core.CoreService;
34import org.onosproject.kubevirtnetworking.api.KubevirtFlowRuleService;
35import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
Jian Lifc7e6cf2021-04-08 11:13:24 +090036import org.onosproject.kubevirtnetworking.api.KubevirtNetworkAdminService;
Jian Li556709c2021-02-03 17:54:28 +090037import org.onosproject.kubevirtnetworking.api.KubevirtNetworkEvent;
38import org.onosproject.kubevirtnetworking.api.KubevirtNetworkListener;
39import org.onosproject.kubevirtnetworking.api.KubevirtNetworkService;
Daniel Parkbabde9c2021-03-09 13:37:42 +090040import org.onosproject.kubevirtnetworking.api.KubevirtPort;
41import org.onosproject.kubevirtnetworking.api.KubevirtPortEvent;
42import org.onosproject.kubevirtnetworking.api.KubevirtPortListener;
43import org.onosproject.kubevirtnetworking.api.KubevirtPortService;
Daniel Park2884b232021-03-04 18:58:47 +090044import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
45import org.onosproject.kubevirtnetworking.api.KubevirtRouterAdminService;
46import org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent;
47import org.onosproject.kubevirtnetworking.api.KubevirtRouterListener;
Jian Li556709c2021-02-03 17:54:28 +090048import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
49import org.onosproject.kubevirtnode.api.KubevirtNode;
50import org.onosproject.kubevirtnode.api.KubevirtNodeEvent;
51import org.onosproject.kubevirtnode.api.KubevirtNodeListener;
52import org.onosproject.kubevirtnode.api.KubevirtNodeService;
53import org.onosproject.net.Device;
54import org.onosproject.net.DeviceId;
55import org.onosproject.net.PortNumber;
56import org.onosproject.net.behaviour.BridgeConfig;
57import org.onosproject.net.behaviour.BridgeDescription;
58import org.onosproject.net.behaviour.BridgeName;
59import org.onosproject.net.behaviour.ControllerInfo;
60import org.onosproject.net.behaviour.DefaultBridgeDescription;
61import org.onosproject.net.behaviour.DefaultPatchDescription;
62import org.onosproject.net.behaviour.InterfaceConfig;
63import org.onosproject.net.behaviour.PatchDescription;
64import org.onosproject.net.device.DeviceAdminService;
Daniel Parka8968802021-02-25 09:14:22 +090065import org.onosproject.net.driver.DriverService;
Jian Li556709c2021-02-03 17:54:28 +090066import org.onosproject.net.flow.DefaultTrafficSelector;
67import org.onosproject.net.flow.DefaultTrafficTreatment;
68import org.onosproject.net.flow.TrafficSelector;
69import org.onosproject.net.flow.TrafficTreatment;
70import org.osgi.service.component.annotations.Activate;
71import org.osgi.service.component.annotations.Component;
72import org.osgi.service.component.annotations.Deactivate;
73import org.osgi.service.component.annotations.Reference;
74import org.osgi.service.component.annotations.ReferenceCardinality;
75import org.slf4j.Logger;
76
77import java.util.List;
78import java.util.Objects;
Daniel Park2884b232021-03-04 18:58:47 +090079import java.util.Set;
Jian Li556709c2021-02-03 17:54:28 +090080import java.util.concurrent.ExecutorService;
81
82import static java.lang.Thread.sleep;
83import static java.util.concurrent.Executors.newSingleThreadExecutor;
Jian Li858ccd72021-02-04 17:25:01 +090084import static org.onlab.packet.ICMP.CODE_ECHO_REQEUST;
85import static org.onlab.packet.ICMP.TYPE_ECHO_REPLY;
86import static org.onlab.packet.ICMP.TYPE_ECHO_REQUEST;
Jian Li556709c2021-02-03 17:54:28 +090087import static org.onlab.util.Tools.groupedThreads;
Daniel Parkbabde9c2021-03-09 13:37:42 +090088import static org.onosproject.kubevirtnetworking.api.Constants.FORWARDING_TABLE;
Jian Lif89d9602021-04-27 19:05:49 +090089import static org.onosproject.kubevirtnetworking.api.Constants.GW_ENTRY_TABLE;
Jian Li556709c2021-02-03 17:54:28 +090090import static org.onosproject.kubevirtnetworking.api.Constants.KUBEVIRT_NETWORKING_APP_ID;
Jian Li8f944d42021-03-23 00:43:29 +090091import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_DEFAULT_RULE;
Jian Li858ccd72021-02-04 17:25:01 +090092import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
Jian Li556709c2021-02-03 17:54:28 +090093import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_DHCP_RULE;
Jian Li858ccd72021-02-04 17:25:01 +090094import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_FORWARDING_RULE;
95import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ICMP_RULE;
Daniel Parkbabde9c2021-03-09 13:37:42 +090096import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_INTERNAL_ROUTING_RULE;
Jian Li8f944d42021-03-23 00:43:29 +090097import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_IP_EGRESS_RULE;
98import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_IP_INGRESS_RULE;
Daniel Parkf3136042021-03-10 07:49:11 +090099import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_TUNNEL_RULE;
Jian Li8f944d42021-03-23 00:43:29 +0900100import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ACL_EGRESS_TABLE;
101import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ACL_INGRESS_TABLE;
Jian Li858ccd72021-02-04 17:25:01 +0900102import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ARP_TABLE;
Jian Li556709c2021-02-03 17:54:28 +0900103import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_DHCP_TABLE;
104import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_FORWARDING_TABLE;
Jian Li858ccd72021-02-04 17:25:01 +0900105import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ICMP_TABLE;
Jian Li556709c2021-02-03 17:54:28 +0900106import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_INBOUND_TABLE;
Jian Li858ccd72021-02-04 17:25:01 +0900107import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_TO_TUNNEL_PREFIX;
Daniel Parkf3136042021-03-10 07:49:11 +0900108import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_DEFAULT_TABLE;
Jian Li858ccd72021-02-04 17:25:01 +0900109import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_TO_TENANT_PREFIX;
Daniel Park4cb120b2021-03-24 12:30:50 +0900110import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.FLAT;
111import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.VLAN;
Daniel Park2884b232021-03-04 18:58:47 +0900112import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.gatewayNodeForSpecifiedRouter;
Daniel Parkbabde9c2021-03-09 13:37:42 +0900113import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterForKubevirtNetwork;
114import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterForKubevirtPort;
Daniel Parkf3136042021-03-10 07:49:11 +0900115import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterMacAddress;
116import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.portNumber;
Jian Li94b6d162021-04-15 17:09:11 +0900117import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.resolveHostname;
Jian Li556709c2021-02-03 17:54:28 +0900118import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.segmentIdHex;
Daniel Parkf3136042021-03-10 07:49:11 +0900119import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.tunnelPort;
120import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.tunnelToTenantPort;
Jian Li858ccd72021-02-04 17:25:01 +0900121import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.NXM_NX_IP_TTL;
122import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.NXM_OF_ICMP_TYPE;
Daniel Parkf3136042021-03-10 07:49:11 +0900123import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildExtension;
Jian Li858ccd72021-02-04 17:25:01 +0900124import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildLoadExtension;
125import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveArpShaToThaExtension;
126import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveArpSpaToTpaExtension;
127import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveEthSrcToDstExtension;
128import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveIpSrcToDstExtension;
Jian Li556709c2021-02-03 17:54:28 +0900129import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_BRIDGE;
Daniel Parkf3136042021-03-10 07:49:11 +0900130import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_TO_INTEGRATION;
Daniel Parka8968802021-02-25 09:14:22 +0900131import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
132import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.WORKER;
Jian Li556709c2021-02-03 17:54:28 +0900133import static org.slf4j.LoggerFactory.getLogger;
134
135/**
136 * Handles kubevirt network events.
137 */
138@Component(immediate = true)
139public class KubevirtNetworkHandler {
140 protected final Logger log = getLogger(getClass());
141 private static final String DEFAULT_OF_PROTO = "tcp";
142 private static final int DEFAULT_OFPORT = 6653;
143 private static final int DPID_BEGIN = 3;
Jian Liea1ead72021-05-28 11:00:07 +0900144 private static final long SLEEP_MS = 3000;
145 private static final long SLEEP_LARGE_MS = 5000;
Jian Li858ccd72021-02-04 17:25:01 +0900146 private static final int DEFAULT_TTL = 0xff;
Jian Li556709c2021-02-03 17:54:28 +0900147
148 @Reference(cardinality = ReferenceCardinality.MANDATORY)
149 protected CoreService coreService;
150
151 @Reference(cardinality = ReferenceCardinality.MANDATORY)
152 protected ClusterService clusterService;
153
154 @Reference(cardinality = ReferenceCardinality.MANDATORY)
155 protected LeadershipService leadershipService;
156
157 @Reference(cardinality = ReferenceCardinality.MANDATORY)
158 protected DeviceAdminService deviceService;
159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY)
161 protected KubevirtApiConfigService apiConfigService;
162
163 @Reference(cardinality = ReferenceCardinality.MANDATORY)
164 protected KubevirtNodeService nodeService;
165
166 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Lifc7e6cf2021-04-08 11:13:24 +0900167 protected KubevirtNetworkAdminService networkService;
Jian Li556709c2021-02-03 17:54:28 +0900168
169 @Reference(cardinality = ReferenceCardinality.MANDATORY)
170 protected KubevirtFlowRuleService flowService;
171
Daniel Parka8968802021-02-25 09:14:22 +0900172 @Reference(cardinality = ReferenceCardinality.MANDATORY)
173 protected DriverService driverService;
174
Daniel Park2884b232021-03-04 18:58:47 +0900175 @Reference(cardinality = ReferenceCardinality.MANDATORY)
176 protected KubevirtRouterAdminService kubevirtRouterService;
177
Daniel Parkbabde9c2021-03-09 13:37:42 +0900178 @Reference(cardinality = ReferenceCardinality.MANDATORY)
179 protected KubevirtPortService kubevirtPortService;
180
181 @Reference(cardinality = ReferenceCardinality.MANDATORY)
182 protected KubevirtNetworkService kubevirtNetworkService;
183
184 @Reference(cardinality = ReferenceCardinality.MANDATORY)
185 protected KubevirtNodeService kubevirtNodeService;
186
Jian Li556709c2021-02-03 17:54:28 +0900187 private final KubevirtNetworkListener networkListener = new InternalNetworkEventListener();
188 private final KubevirtNodeListener nodeListener = new InternalNodeEventListener();
Daniel Parkbabde9c2021-03-09 13:37:42 +0900189 private final KubevirtPortListener portListener = new InternalKubevirtPortListener();
Jian Li556709c2021-02-03 17:54:28 +0900190
Daniel Park2884b232021-03-04 18:58:47 +0900191 private final InternalRouterEventListener kubevirtRouterlistener =
192 new InternalRouterEventListener();
193
Jian Li556709c2021-02-03 17:54:28 +0900194 private final ExecutorService eventExecutor = newSingleThreadExecutor(
195 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
196
197 private ApplicationId appId;
198 private NodeId localNodeId;
199
200 @Activate
201 protected void activate() {
202 appId = coreService.registerApplication(KUBEVIRT_NETWORKING_APP_ID);
203 localNodeId = clusterService.getLocalNode().id();
Jian Li556709c2021-02-03 17:54:28 +0900204 leadershipService.runForLeadership(appId.name());
205
Daniel Parkbabde9c2021-03-09 13:37:42 +0900206 networkService.addListener(networkListener);
207 nodeService.addListener(nodeListener);
208 kubevirtPortService.addListener(portListener);
Daniel Park2884b232021-03-04 18:58:47 +0900209 kubevirtRouterService.addListener(kubevirtRouterlistener);
210
Jian Li556709c2021-02-03 17:54:28 +0900211 log.info("Started");
212 }
213
214 @Deactivate
215 protected void deactivate() {
216 networkService.removeListener(networkListener);
217 nodeService.removeListener(nodeListener);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900218 kubevirtPortService.removeListener(portListener);
Daniel Park2884b232021-03-04 18:58:47 +0900219 kubevirtRouterService.removeListener(kubevirtRouterlistener);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900220 leadershipService.withdraw(appId.name());
Jian Li556709c2021-02-03 17:54:28 +0900221 eventExecutor.shutdown();
222
223 log.info("Stopped");
224 }
225
226 private void createBridge(KubevirtNode node, KubevirtNetwork network) {
227
Jian Li8f944d42021-03-23 00:43:29 +0900228 Device tenantBridge = deviceService.getDevice(network.tenantDeviceId(node.hostname()));
229 if (tenantBridge != null) {
230 log.warn("The tenant bridge {} already exists at node {}",
Jian Li556709c2021-02-03 17:54:28 +0900231 network.tenantBridgeName(), node.hostname());
Daniel Parkf3136042021-03-10 07:49:11 +0900232 setDefaultRulesForTenantNetwork(node, network);
Jian Li556709c2021-02-03 17:54:28 +0900233 return;
234 }
235
236 Device device = deviceService.getDevice(node.ovsdb());
237
Jian Li94b6d162021-04-15 17:09:11 +0900238 IpAddress serverIp;
239 String serviceFqdn = apiConfigService.apiConfig().serviceFqdn();
240 IpAddress serviceIp = null;
241
242 if (serviceFqdn != null) {
243 serviceIp = resolveHostname(serviceFqdn);
244 }
245
246 if (serviceIp != null) {
247 serverIp = serviceIp;
248 } else {
249 serverIp = apiConfigService.apiConfig().ipAddress();
250 }
251
Jian Li556709c2021-02-03 17:54:28 +0900252 ControllerInfo controlInfo =
253 new ControllerInfo(serverIp, DEFAULT_OFPORT, DEFAULT_OF_PROTO);
254 List<ControllerInfo> controllers = Lists.newArrayList(controlInfo);
255
256 String dpid = network.tenantDeviceId(
257 node.hostname()).toString().substring(DPID_BEGIN);
258
259 BridgeDescription.Builder builder = DefaultBridgeDescription.builder()
260 .name(network.tenantBridgeName())
261 .failMode(BridgeDescription.FailMode.SECURE)
262 .datapathId(dpid)
263 .disableInBand()
264 .controllers(controllers);
265
266 BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
267 bridgeConfig.addBridge(builder.build());
268 }
269
270 private void removeBridge(KubevirtNode node, KubevirtNetwork network) {
271 Device device = deviceService.getDevice(node.ovsdb());
272
273 BridgeName bridgeName = BridgeName.bridgeName(network.tenantBridgeName());
274
275 BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
276 bridgeConfig.deleteBridge(bridgeName);
277 deviceService.removeDevice(network.tenantDeviceId(node.hostname()));
278 }
279
Daniel Parkf3136042021-03-10 07:49:11 +0900280 private void createPatchTenantInterface(KubevirtNode node, KubevirtNetwork network) {
Jian Li556709c2021-02-03 17:54:28 +0900281 Device device = deviceService.getDevice(node.ovsdb());
282
283 if (device == null || !device.is(InterfaceConfig.class)) {
284 log.error("Failed to create patch interface on {}", node.ovsdb());
285 return;
286 }
287
288 InterfaceConfig ifaceConfig = device.as(InterfaceConfig.class);
289
Jian Li858ccd72021-02-04 17:25:01 +0900290 String tenantToTunIntf =
291 TENANT_TO_TUNNEL_PREFIX + segmentIdHex(network.segmentId());
292 String tunToTenantIntf =
293 TUNNEL_TO_TENANT_PREFIX + segmentIdHex(network.segmentId());
Jian Li556709c2021-02-03 17:54:28 +0900294
Jian Li858ccd72021-02-04 17:25:01 +0900295 // tenant bridge -> tunnel bridge
296 PatchDescription brTenantTunPatchDesc =
Jian Li556709c2021-02-03 17:54:28 +0900297 DefaultPatchDescription.builder()
298 .deviceId(network.tenantBridgeName())
Jian Li858ccd72021-02-04 17:25:01 +0900299 .ifaceName(tenantToTunIntf)
300 .peer(tunToTenantIntf)
Jian Li556709c2021-02-03 17:54:28 +0900301 .build();
302
Jian Li858ccd72021-02-04 17:25:01 +0900303 ifaceConfig.addPatchMode(tenantToTunIntf, brTenantTunPatchDesc);
Jian Li556709c2021-02-03 17:54:28 +0900304
Jian Li858ccd72021-02-04 17:25:01 +0900305 // tunnel bridge -> tenant bridge
306 PatchDescription brTunTenantPatchDesc =
Jian Li556709c2021-02-03 17:54:28 +0900307 DefaultPatchDescription.builder()
308 .deviceId(TUNNEL_BRIDGE)
Jian Li858ccd72021-02-04 17:25:01 +0900309 .ifaceName(tunToTenantIntf)
310 .peer(tenantToTunIntf)
Jian Li556709c2021-02-03 17:54:28 +0900311 .build();
Jian Li858ccd72021-02-04 17:25:01 +0900312 ifaceConfig.addPatchMode(tunToTenantIntf, brTunTenantPatchDesc);
Jian Li556709c2021-02-03 17:54:28 +0900313 }
314
Jian Liea1ead72021-05-28 11:00:07 +0900315 private void removeAllFlows(KubevirtNode node, KubevirtNetwork network) {
316 DeviceId deviceId = network.tenantDeviceId(node.hostname());
317 flowService.purgeRules(deviceId);
318 }
319
Jian Li556709c2021-02-03 17:54:28 +0900320 private void removePatchInterface(KubevirtNode node, KubevirtNetwork network) {
321 Device device = deviceService.getDevice(node.ovsdb());
322
323 if (device == null || !device.is(InterfaceConfig.class)) {
324 log.error("Failed to create patch interface on {}", node.ovsdb());
325 return;
326 }
327
328 InterfaceConfig ifaceConfig = device.as(InterfaceConfig.class);
329
Jian Li858ccd72021-02-04 17:25:01 +0900330 String tunToIntIntf = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(network.segmentId());
Jian Li556709c2021-02-03 17:54:28 +0900331
332 ifaceConfig.removePatchMode(tunToIntIntf);
333 }
334
Jian Li8f944d42021-03-23 00:43:29 +0900335 private void setGatewayArpRulesForTenantNetwork(KubevirtNode node,
336 KubevirtNetwork network) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900337
338 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
339 if (router == null) {
340 return;
341 }
342
343 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
344 if (electedGw == null) {
345 return;
346 }
347
Jian Li8f944d42021-03-23 00:43:29 +0900348 setGatewayArpRuleForTenantInternalNetwork(router, network, TENANT_ARP_TABLE,
349 electedGw.intgBridge(), network.tenantDeviceId(node.hostname()), true);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900350 }
351
Jian Li8f944d42021-03-23 00:43:29 +0900352 private void setGatewayIcmpRulesForTenantNetwork(KubevirtNode node,
353 KubevirtNetwork network) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900354 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
355 if (router == null) {
356 return;
357 }
358
359 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
360 if (electedGw == null) {
361 return;
362 }
363
Jian Li8f944d42021-03-23 00:43:29 +0900364 setGatewayIcmpRuleForTenantInternalNetwork(router, network, TENANT_ICMP_TABLE,
365 electedGw.intgBridge(), network.tenantDeviceId(node.hostname()), true);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900366 }
367
Jian Li8f944d42021-03-23 00:43:29 +0900368 private void setGatewayRuleToWorkerNodeWhenNodeCreated(KubevirtNode node,
369 KubevirtNetwork network) {
Daniel Parkf3136042021-03-10 07:49:11 +0900370 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
371 if (router == null) {
372 return;
373 }
Daniel Parkbabde9c2021-03-09 13:37:42 +0900374
Daniel Parkf3136042021-03-10 07:49:11 +0900375 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
376 if (electedGw == null) {
377 return;
378 }
379
Jian Li8f944d42021-03-23 00:43:29 +0900380 setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
381 electedGw.intgBridge(), node, true);
Daniel Parkf3136042021-03-10 07:49:11 +0900382 }
383
Jian Li8f944d42021-03-23 00:43:29 +0900384 private void setDefaultRulesForTenantNetwork(KubevirtNode node,
385 KubevirtNetwork network) {
Jian Li556709c2021-02-03 17:54:28 +0900386 DeviceId deviceId = network.tenantDeviceId(node.hostname());
387
388 while (!deviceService.isAvailable(deviceId)) {
389 log.warn("Device {} is not ready for installing rules", deviceId);
390
391 try {
392 sleep(SLEEP_MS);
393 } catch (InterruptedException e) {
394 log.error("Failed to check device availability", e);
395 }
396 }
397
398 flowService.connectTables(deviceId, TENANT_INBOUND_TABLE, TENANT_DHCP_TABLE);
Jian Li858ccd72021-02-04 17:25:01 +0900399 flowService.connectTables(deviceId, TENANT_DHCP_TABLE, TENANT_ARP_TABLE);
400 flowService.connectTables(deviceId, TENANT_ARP_TABLE, TENANT_ICMP_TABLE);
401 flowService.connectTables(deviceId, TENANT_ICMP_TABLE, TENANT_FORWARDING_TABLE);
Jian Li556709c2021-02-03 17:54:28 +0900402
Jian Li8f944d42021-03-23 00:43:29 +0900403 setArpRuleForTenantNetwork(deviceId, true);
Daniel Parkf3136042021-03-10 07:49:11 +0900404 setDhcpRuleForTenantNetwork(deviceId, true);
Jian Li556709c2021-02-03 17:54:28 +0900405 setForwardingRule(deviceId, true);
406
Jian Li8f944d42021-03-23 00:43:29 +0900407 // security group related rules
408 setTenantIngressTransitionRule(network, network.tenantDeviceId(node.hostname()), true);
Jian Lif89d9602021-04-27 19:05:49 +0900409 setTenantEgressTransitionRule(network.tenantDeviceId(node.hostname()), true);
Jian Li8f944d42021-03-23 00:43:29 +0900410
Jian Li556709c2021-02-03 17:54:28 +0900411 log.info("Install default flow rules for tenant bridge {}", network.tenantBridgeName());
412 }
413
Daniel Parkf3136042021-03-10 07:49:11 +0900414 private void setDhcpRuleForTenantNetwork(DeviceId deviceId, boolean install) {
Jian Li556709c2021-02-03 17:54:28 +0900415 TrafficSelector selector = DefaultTrafficSelector.builder()
416 .matchEthType(Ethernet.TYPE_IPV4)
417 .matchIPProtocol(IPv4.PROTOCOL_UDP)
418 .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
419 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
420 .build();
421
422 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
423 .punt()
424 .build();
425
426 flowService.setRule(
427 appId,
428 deviceId,
429 selector,
430 treatment,
431 PRIORITY_DHCP_RULE,
432 TENANT_DHCP_TABLE,
433 install);
434 }
435
Jian Li858ccd72021-02-04 17:25:01 +0900436 private void setForwardingRule(DeviceId deviceId, boolean install) {
Jian Li556709c2021-02-03 17:54:28 +0900437 TrafficSelector selector = DefaultTrafficSelector.builder().build();
438 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
439 .setOutput(PortNumber.NORMAL)
440 .build();
441
442 flowService.setRule(
443 appId,
444 deviceId,
445 selector,
446 treatment,
Jian Li858ccd72021-02-04 17:25:01 +0900447 PRIORITY_FORWARDING_RULE,
Jian Li556709c2021-02-03 17:54:28 +0900448 TENANT_FORWARDING_TABLE,
449 install);
450 }
451
Daniel Park2884b232021-03-04 18:58:47 +0900452 private void initGatewayNodeForInternalNetwork(KubevirtNetwork network,
453 KubevirtRouter router,
454 KubevirtNode electedGateway,
455 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900456 switch (network.type()) {
457 case VXLAN:
458 case GRE:
459 case GENEVE:
Jian Li8f944d42021-03-23 00:43:29 +0900460 setDefaultEgressRuleToGatewayNode(router, network,
461 electedGateway.intgBridge(), install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900462 kubevirtNodeService.completeNodes(WORKER).forEach(node -> {
Jian Li8f944d42021-03-23 00:43:29 +0900463 setGatewayArpRuleForTenantInternalNetwork(router, network,
464 TENANT_ARP_TABLE, electedGateway.intgBridge(),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900465 network.tenantDeviceId(node.hostname()), install);
Jian Li8f944d42021-03-23 00:43:29 +0900466 setGatewayIcmpRuleForTenantInternalNetwork(router, network,
467 TENANT_ICMP_TABLE, electedGateway.intgBridge(),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900468 network.tenantDeviceId(node.hostname()), install);
Jian Li517597a2021-03-22 11:04:52 +0900469 setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
Daniel Parkf3136042021-03-10 07:49:11 +0900470 electedGateway.intgBridge(), node, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900471 });
Daniel Park4cb120b2021-03-24 12:30:50 +0900472 setGatewayProviderInterNetworkRoutingWithinSameRouter(network, router, electedGateway, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900473 break;
474 case FLAT:
475 case VLAN:
Jian Li8f944d42021-03-23 00:43:29 +0900476 setGatewayArpRuleForProviderInternalNetwork(router, network,
Jian Lif89d9602021-04-27 19:05:49 +0900477 GW_ENTRY_TABLE, electedGateway.intgBridge(), install);
Jian Li8f944d42021-03-23 00:43:29 +0900478 setGatewayIcmpRuleForProviderInternalNetwork(router, network,
Jian Lif89d9602021-04-27 19:05:49 +0900479 GW_ENTRY_TABLE, electedGateway.intgBridge(), install);
Jian Li8f944d42021-03-23 00:43:29 +0900480 setGatewayProviderInterNetworkRoutingWithinSameRouter(network,
481 router, electedGateway, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900482 break;
483 default:
484 // do nothing
485 break;
486 }
Daniel Park2884b232021-03-04 18:58:47 +0900487 }
488
Jian Li517597a2021-03-22 11:04:52 +0900489 private void setDefaultGatewayRuleToWorkerNodeTunBridge(KubevirtRouter router,
490 KubevirtNetwork network,
491 DeviceId gwDeviceId,
492 KubevirtNode workerNode,
493 boolean install) {
Daniel Parkf3136042021-03-10 07:49:11 +0900494 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900495
Daniel Parkf3136042021-03-10 07:49:11 +0900496 if (routerMacAddress == null) {
497 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
498 "there's no br-int port for device {}", gwDeviceId);
499 return;
500 }
501
502 KubevirtNode gwNode = kubevirtNodeService.node(gwDeviceId);
503
504 if (gwNode == null) {
505 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
506 "there's no gateway node for device {}", gwDeviceId);
507 return;
508 }
509
510
511 PortNumber patchPortNumber = tunnelToTenantPort(workerNode, network);
512 if (patchPortNumber == null) {
513 return;
514 }
515
516 PortNumber tunnelPortNumber = tunnelPort(workerNode, network);
517 if (tunnelPortNumber == null) {
518 return;
519 }
520
521 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
522 .matchInPort(patchPortNumber)
523 .matchEthType(Ethernet.TYPE_IPV4)
524 .matchEthDst((routerMacAddress));
525
526 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
527 .setTunnelId(Long.parseLong(network.segmentId()))
528 .extension(buildExtension(
529 deviceService,
530 workerNode.tunBridge(),
531 gwNode.dataIp().getIp4Address()),
532 workerNode.tunBridge())
533 .setOutput(tunnelPortNumber);
534
535 flowService.setRule(
536 appId,
537 workerNode.tunBridge(),
538 sBuilder.build(),
539 tBuilder.build(),
540 PRIORITY_FORWARDING_RULE,
541 TUNNEL_DEFAULT_TABLE,
542 install);
543 }
544
Jian Li8f944d42021-03-23 00:43:29 +0900545 private void setTenantIngressTransitionRule(KubevirtNetwork network,
546 DeviceId deviceId, boolean install) {
547 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
548 sBuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort())
549 .matchInPort(network.tenantToTunnelPort(deviceId));
550
551 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
552 tBuilder.transition(TENANT_ACL_INGRESS_TABLE);
553
554 flowService.setRule(appId,
555 deviceId,
556 sBuilder.build(),
557 tBuilder.build(),
558 PRIORITY_IP_INGRESS_RULE,
559 TENANT_ICMP_TABLE,
560 install
561 );
562 }
563
Jian Lif89d9602021-04-27 19:05:49 +0900564 private void setTenantEgressTransitionRule(DeviceId deviceId, boolean install) {
Jian Li8f944d42021-03-23 00:43:29 +0900565 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
566 sBuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort());
567
568 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
569 tBuilder.transition(TENANT_ACL_EGRESS_TABLE);
570
571 flowService.setRule(appId,
572 deviceId,
573 sBuilder.build(),
574 tBuilder.build(),
575 PRIORITY_IP_EGRESS_RULE,
576 TENANT_ICMP_TABLE,
577 install
578 );
579 }
580
Daniel Parkf3136042021-03-10 07:49:11 +0900581 private void setDefaultEgressRuleToGatewayNode(KubevirtRouter router,
582 KubevirtNetwork network,
583 DeviceId gwDeviceId,
584 boolean install) {
585 MacAddress routerMacAddress = getRouterMacAddress(router);
586
587 if (routerMacAddress == null) {
588 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
589 "there's no br-int port for device {}", gwDeviceId);
590 return;
591 }
592
593 KubevirtNode gwNode = kubevirtNodeService.node(gwDeviceId);
594
595 if (gwNode == null) {
596 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
597 "there's no gateway node for device {}", gwDeviceId);
598 return;
599 }
600
601 PortNumber tunToIntPortNum = portNumber(gwNode.tunBridge(), TUNNEL_TO_INTEGRATION);
602
603 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
604 .matchTunnelId(Long.parseLong(network.segmentId()));
605
606 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
607 .setOutput(tunToIntPortNum);
608
609 flowService.setRule(
610 appId,
611 gwNode.tunBridge(),
612 sBuilder.build(),
613 tBuilder.build(),
614 PRIORITY_TUNNEL_RULE,
615 TUNNEL_DEFAULT_TABLE,
616 install);
617 }
618
619
620 private void setGatewayIcmpRuleForTenantInternalNetwork(KubevirtRouter router,
621 KubevirtNetwork network,
622 int tableNum,
623 DeviceId gwDeviceId,
624 DeviceId tenantDeviceId,
625 boolean install) {
626 MacAddress routerMacAddress = getRouterMacAddress(router);
627
628 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900629 log.warn("Setting gateway ICMP rule for internal network because " +
630 "there's no br-int port for device {}", gwDeviceId);
631 return;
632 }
633
634 Device device = deviceService.getDevice(tenantDeviceId);
635
636 if (device == null) {
637 log.warn("Setting gateway icmp rule for internal network because " +
638 "there's no tenant device for {} to install gateway arp rule",
639 tenantDeviceId);
640 return;
641 }
642
643
644 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
645 .matchEthType(Ethernet.TYPE_IPV4)
646 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
647 .matchIcmpType(TYPE_ECHO_REQUEST)
648 .matchIcmpCode(CODE_ECHO_REQEUST)
649 .matchIPDst(IpPrefix.valueOf(network.gatewayIp(), 32));
650
651 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
652 .extension(buildMoveEthSrcToDstExtension(device), device.id())
653 .extension(buildMoveIpSrcToDstExtension(device), device.id())
654 .extension(buildLoadExtension(device,
655 NXM_NX_IP_TTL, DEFAULT_TTL), device.id())
656 .extension(buildLoadExtension(device,
657 NXM_OF_ICMP_TYPE, TYPE_ECHO_REPLY), device.id())
658 .setIpSrc(network.gatewayIp())
Daniel Parkf3136042021-03-10 07:49:11 +0900659 .setEthSrc(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900660 .setOutput(PortNumber.IN_PORT);
661
662 flowService.setRule(
663 appId,
664 tenantDeviceId,
665 sBuilder.build(),
666 tBuilder.build(),
667 PRIORITY_ICMP_RULE,
668 tableNum,
669 install);
670 }
671
Jian Li8f944d42021-03-23 00:43:29 +0900672 private void setArpRuleForTenantNetwork(DeviceId tenantDeviceId,
673 boolean install) {
674 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
675 .matchEthType(EthType.EtherType.ARP.ethType().toShort());
676
677 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
678 .transition(TENANT_FORWARDING_TABLE);
679
680 flowService.setRule(
681 appId,
682 tenantDeviceId,
683 sBuilder.build(),
684 tBuilder.build(),
685 PRIORITY_ARP_DEFAULT_RULE,
686 TENANT_ARP_TABLE,
687 install
688 );
689 }
690
Daniel Parkf3136042021-03-10 07:49:11 +0900691 private void setGatewayArpRuleForTenantInternalNetwork(KubevirtRouter router,
692 KubevirtNetwork network,
693 int tableNum,
694 DeviceId gwDeviceId,
695 DeviceId tenantDeviceId,
696 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900697
Daniel Parkf3136042021-03-10 07:49:11 +0900698 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900699
Daniel Parkf3136042021-03-10 07:49:11 +0900700 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900701 log.warn("Setting gateway arp rule for internal network because " +
702 "there's no br-int port for device {}", gwDeviceId);
703 return;
704 }
705
706 Device device = deviceService.getDevice(tenantDeviceId);
707
708 if (device == null) {
709 log.warn("Setting gateway arp rule for internal network because " +
710 "there's no tenant device for {} to install gateway arp rule",
711 tenantDeviceId);
712 return;
713 }
714
715
716 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
717 sBuilder.matchEthType(EthType.EtherType.ARP.ethType().toShort())
718 .matchArpOp(ARP.OP_REQUEST)
719 .matchArpTpa(Ip4Address.valueOf(network.gatewayIp().toString()));
720
721 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
722 tBuilder.extension(buildMoveEthSrcToDstExtension(device), device.id())
723 .extension(buildMoveArpShaToThaExtension(device), device.id())
724 .extension(buildMoveArpSpaToTpaExtension(device), device.id())
725 .setArpOp(ARP.OP_REPLY)
Daniel Parkf3136042021-03-10 07:49:11 +0900726 .setArpSha(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900727 .setArpSpa(Ip4Address.valueOf(network.gatewayIp().toString()))
Daniel Parkf3136042021-03-10 07:49:11 +0900728 .setEthSrc(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900729 .setOutput(PortNumber.IN_PORT);
730
731 flowService.setRule(
732 appId,
733 device.id(),
734 sBuilder.build(),
735 tBuilder.build(),
736 PRIORITY_ARP_GATEWAY_RULE,
737 tableNum,
738 install
739 );
740 }
741
Daniel Parkf3136042021-03-10 07:49:11 +0900742 private void setGatewayProviderInterNetworkRoutingWithinSameRouter(
Daniel Parkbabde9c2021-03-09 13:37:42 +0900743 KubevirtNetwork network, KubevirtRouter router, KubevirtNode gatewayNode, boolean install) {
Daniel Park2884b232021-03-04 18:58:47 +0900744 router.internal().forEach(srcNetwork -> {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900745 if (srcNetwork.equals(network.networkId())
746 || kubevirtNetworkService.network(srcNetwork) == null) {
Daniel Park2884b232021-03-04 18:58:47 +0900747 return;
748 }
749
Daniel Parkbabde9c2021-03-09 13:37:42 +0900750 kubevirtPortService.ports(network.networkId()).forEach(port -> {
Daniel Parkf3136042021-03-10 07:49:11 +0900751 setGatewayInterNetworkRoutingFromNetworkToPort(router, kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900752 port, gatewayNode, install);
753 });
Daniel Park2884b232021-03-04 18:58:47 +0900754 });
755 }
756
Daniel Parkf3136042021-03-10 07:49:11 +0900757 private void setGatewayInterNetworkRoutingFromNetworkToPort(KubevirtRouter router,
758 KubevirtNetwork srcNetwork,
759 KubevirtPort dstPort,
760 KubevirtNode gatewayNode,
761 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900762 Device gwDevice = deviceService.getDevice(gatewayNode.intgBridge());
763
764 if (gwDevice == null) {
765 log.warn("Failed to set internal network routing rule because " +
766 "there's no device Id for device {}", gatewayNode.intgBridge());
767 return;
768 }
769
Daniel Parkf3136042021-03-10 07:49:11 +0900770 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900771
Daniel Parkf3136042021-03-10 07:49:11 +0900772 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900773 log.warn("Failed to set internal network routing rule because " +
774 "there's no br-int port for device {}", gatewayNode.intgBridge());
775 return;
776 }
777
Daniel Park4cb120b2021-03-24 12:30:50 +0900778 TrafficSelector.Builder sBuilder;
779 TrafficTreatment treatment;
Daniel Parkbabde9c2021-03-09 13:37:42 +0900780
Daniel Park4cb120b2021-03-24 12:30:50 +0900781 if (srcNetwork.type() == FLAT || srcNetwork.type() == VLAN) {
782 sBuilder = DefaultTrafficSelector.builder()
783 .matchEthType(Ethernet.TYPE_IPV4)
784 .matchEthDst(routerMacAddress)
785 .matchIPSrc(IpPrefix.valueOf(srcNetwork.cidr()))
786 .matchIPDst(IpPrefix.valueOf(dstPort.ipAddress(), 32));
Daniel Parkbabde9c2021-03-09 13:37:42 +0900787
Daniel Park4cb120b2021-03-24 12:30:50 +0900788 treatment = DefaultTrafficTreatment.builder()
789 .setEthSrc(routerMacAddress)
790 .setEthDst(dstPort.macAddress())
791 .transition(FORWARDING_TABLE)
792 .build();
793
794 flowService.setRule(
795 appId,
796 gwDevice.id(),
797 sBuilder.build(),
798 treatment,
799 PRIORITY_INTERNAL_ROUTING_RULE,
Jian Lif89d9602021-04-27 19:05:49 +0900800 GW_ENTRY_TABLE,
Daniel Park4cb120b2021-03-24 12:30:50 +0900801 install);
802 } else {
803 KubevirtNetwork dstNetwork = kubevirtNetworkService.network(dstPort.networkId());
804 if (dstNetwork == null) {
805 return;
806 }
807
808 KubevirtNode dstPortWorkerNode = kubevirtNodeService.node(dstPort.deviceId());
809 if (dstPortWorkerNode == null) {
810 return;
811 }
812
813 sBuilder = DefaultTrafficSelector.builder()
814 .matchEthType(Ethernet.TYPE_IPV4)
815 .matchEthDst(routerMacAddress)
816 .matchTunnelId(Long.parseLong(srcNetwork.segmentId()))
817 .matchIPSrc(IpPrefix.valueOf(srcNetwork.cidr()))
818 .matchIPDst(IpPrefix.valueOf(dstPort.ipAddress(), 32));
819
820 treatment = DefaultTrafficTreatment.builder()
821 .setTunnelId(Long.parseLong(dstNetwork.segmentId()))
822 .setEthSrc(routerMacAddress)
823 .setEthDst(dstPort.macAddress())
824 .extension(buildExtension(
825 deviceService,
826 gatewayNode.tunBridge(),
827 dstPortWorkerNode.dataIp().getIp4Address()),
828 gatewayNode.tunBridge())
829 .setOutput(PortNumber.IN_PORT)
830 .build();
831
832 flowService.setRule(
833 appId,
834 gatewayNode.tunBridge(),
835 sBuilder.build(),
836 treatment,
837 PRIORITY_INTERNAL_ROUTING_RULE,
838 TUNNEL_DEFAULT_TABLE,
839 install);
840 }
Daniel Parkbabde9c2021-03-09 13:37:42 +0900841 }
842
Daniel Parkf3136042021-03-10 07:49:11 +0900843 private void setGatewayArpRuleForProviderInternalNetwork(KubevirtRouter router, KubevirtNetwork network,
844 int tableNum, DeviceId gwDeviceId, boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900845
846
847 Device device = deviceService.getDevice(gwDeviceId);
Daniel Parkf3136042021-03-10 07:49:11 +0900848 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900849
Daniel Parkf3136042021-03-10 07:49:11 +0900850 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900851 log.warn("Setting gateway arp rule for internal network because " +
852 "there's no br-int port for device {}", gwDeviceId);
Daniel Park2884b232021-03-04 18:58:47 +0900853 return;
854 }
855
Jian Li858ccd72021-02-04 17:25:01 +0900856 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
857 sBuilder.matchEthType(EthType.EtherType.ARP.ethType().toShort())
858 .matchArpOp(ARP.OP_REQUEST)
859 .matchArpTpa(Ip4Address.valueOf(network.gatewayIp().toString()));
860
861 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
862 tBuilder.extension(buildMoveEthSrcToDstExtension(device), device.id())
863 .extension(buildMoveArpShaToThaExtension(device), device.id())
864 .extension(buildMoveArpSpaToTpaExtension(device), device.id())
865 .setArpOp(ARP.OP_REPLY)
Daniel Parkf3136042021-03-10 07:49:11 +0900866 .setArpSha(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900867 .setArpSpa(Ip4Address.valueOf(network.gatewayIp().toString()))
Daniel Parkf3136042021-03-10 07:49:11 +0900868 .setEthSrc(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900869 .setOutput(PortNumber.IN_PORT);
870
871 flowService.setRule(
872 appId,
873 device.id(),
874 sBuilder.build(),
875 tBuilder.build(),
876 PRIORITY_ARP_GATEWAY_RULE,
Daniel Parka8968802021-02-25 09:14:22 +0900877 tableNum,
Jian Li858ccd72021-02-04 17:25:01 +0900878 install
879 );
880 }
881
Daniel Park2884b232021-03-04 18:58:47 +0900882 /**
883 * Sends ICMP echo reply for the ICMP echo request from the kubevirt VM.
884 *
Daniel Parkf3136042021-03-10 07:49:11 +0900885 * @param router kubevirt router
Daniel Park2884b232021-03-04 18:58:47 +0900886 * @param network kubevirt network
887 * @param tableNum flow table number
888 * @param deviceId device id of the selected gateway for the network
889 * @param install install if true, remove otherwise
890 */
Daniel Parkf3136042021-03-10 07:49:11 +0900891 private void setGatewayIcmpRuleForProviderInternalNetwork(KubevirtRouter router, KubevirtNetwork network,
892 int tableNum, DeviceId deviceId, boolean install) {
893 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900894
Daniel Parkf3136042021-03-10 07:49:11 +0900895 if (routerMacAddress == null) {
Daniel Park2884b232021-03-04 18:58:47 +0900896 log.error("Setting gateway ICMP rule for internal network because " +
897 "there's no br-int port for device {}", deviceId);
898 return;
899 }
900
Jian Li858ccd72021-02-04 17:25:01 +0900901 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
902 .matchEthType(Ethernet.TYPE_IPV4)
903 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
904 .matchIcmpType(TYPE_ECHO_REQUEST)
905 .matchIcmpCode(CODE_ECHO_REQEUST)
906 .matchIPDst(IpPrefix.valueOf(network.gatewayIp(), 32));
907
908 Device device = deviceService.getDevice(deviceId);
909 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
910 .extension(buildMoveEthSrcToDstExtension(device), device.id())
911 .extension(buildMoveIpSrcToDstExtension(device), device.id())
912 .extension(buildLoadExtension(device,
913 NXM_NX_IP_TTL, DEFAULT_TTL), device.id())
914 .extension(buildLoadExtension(device,
915 NXM_OF_ICMP_TYPE, TYPE_ECHO_REPLY), device.id())
916 .setIpSrc(network.gatewayIp())
Daniel Parkf3136042021-03-10 07:49:11 +0900917 .setEthSrc(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900918 .setOutput(PortNumber.IN_PORT);
919
920 flowService.setRule(
921 appId,
922 deviceId,
923 sBuilder.build(),
924 tBuilder.build(),
925 PRIORITY_ICMP_RULE,
Daniel Parka8968802021-02-25 09:14:22 +0900926 tableNum,
Jian Li858ccd72021-02-04 17:25:01 +0900927 install);
928 }
929
Daniel Park2884b232021-03-04 18:58:47 +0900930 private class InternalRouterEventListener implements KubevirtRouterListener {
931 private boolean isRelevantHelper() {
932 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
Daniel Parka8968802021-02-25 09:14:22 +0900933 }
934
Daniel Park2884b232021-03-04 18:58:47 +0900935 @Override
936 public void event(KubevirtRouterEvent event) {
937 switch (event.type()) {
938 case KUBEVIRT_ROUTER_CREATED:
939 eventExecutor.execute(() -> processRouterCreation(event.subject()));
940 break;
941 case KUBEVIRT_ROUTER_REMOVED:
942 eventExecutor.execute(() -> processRouterDeletion(event.subject()));
943 break;
944 case KUBEVIRT_ROUTER_UPDATED:
945 eventExecutor.execute(() -> processRouterUpdate(event.subject()));
946 break;
947 case KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED:
948 eventExecutor.execute(() -> processRouterInternalNetworksAttached(event.subject(),
949 event.internal()));
950 break;
951 case KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED:
952 eventExecutor.execute(() -> processRouterInternalNetworksDetached(event.subject(),
953 event.internal()));
954 break;
955 case KUBEVIRT_GATEWAY_NODE_ATTACHED:
956 eventExecutor.execute(() -> processRouterGatewayNodeAttached(event.subject(),
957 event.gateway()));
958 break;
959 case KUBEVIRT_GATEWAY_NODE_DETACHED:
960 eventExecutor.execute(() -> processRouterGatewayNodeDetached(event.subject(),
961 event.gateway()));
962 break;
963 case KUBEVIRT_GATEWAY_NODE_CHANGED:
964 eventExecutor.execute(() -> processRouterGatewayNodeChanged(event.subject(),
965 event.gateway()));
966 break;
Daniel Parka8968802021-02-25 09:14:22 +0900967
Daniel Park2884b232021-03-04 18:58:47 +0900968 default:
969 //do nothing
970 break;
971 }
972 }
973
974 private void processRouterCreation(KubevirtRouter router) {
975 // When a router is created, we performs the election process to associate the router
976 // to the specific gateway. After the election, KubevirtNetwork handler installs bunch of rules
977 // to elected gateway node so that VMs associated to the router can ping to their gateway IP.
978 // SNAT and floating ip rule setup is out of this handler's scope and would be done with the other handlers
979 if (!isRelevantHelper()) {
980 return;
981 }
982 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
983 if (electedGw == null) {
984 return;
985 }
986
987 router.internal().forEach(networkName -> {
988 KubevirtNetwork network = networkService.network(networkName);
989
990 if (network != null) {
991 initGatewayNodeForInternalNetwork(network, router, electedGw, true);
992 }
993 });
994 kubevirtRouterService.updateRouter(router.updatedElectedGateway(electedGw.hostname()));
995 }
996
997 private void processRouterDeletion(KubevirtRouter router) {
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, false);
1011 }
1012 });
1013 }
1014
1015 private void processRouterUpdate(KubevirtRouter router) {
1016 if (!isRelevantHelper()) {
1017 return;
1018 }
1019 if (router.electedGateway() == null) {
1020 return;
1021 }
1022
1023 KubevirtNode electedGw = nodeService.node(router.electedGateway());
1024
1025 router.internal().forEach(networkName -> {
1026 KubevirtNetwork network = networkService.network(networkName);
1027
1028 if (network != null) {
1029 initGatewayNodeForInternalNetwork(network, router, electedGw, true);
1030 }
1031 });
1032 }
1033
1034 private void processRouterInternalNetworksAttached(KubevirtRouter router,
1035 Set<String> attachedInternalNetworks) {
1036 if (!isRelevantHelper()) {
1037 return;
1038 }
1039 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1040 if (electedGw == null) {
1041 return;
1042 }
1043
1044 attachedInternalNetworks.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 processRouterInternalNetworksDetached(KubevirtRouter router,
1054 Set<String> detachedInternalNetworks) {
1055 if (!isRelevantHelper()) {
1056 return;
1057 }
1058 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1059 if (electedGw == null) {
1060 return;
1061 }
1062
1063 detachedInternalNetworks.forEach(networkName -> {
1064 KubevirtNetwork network = networkService.network(networkName);
1065
1066 if (network != null) {
1067 initGatewayNodeForInternalNetwork(network, router, electedGw, false);
1068 }
Daniel Park2884b232021-03-04 18:58:47 +09001069
Daniel Parkbabde9c2021-03-09 13:37:42 +09001070 removeDetachedInternalNetworkRules(network, router, electedGw);
1071 });
1072 }
1073
Jian Li8f944d42021-03-23 00:43:29 +09001074 private void removeDetachedInternalNetworkRules(KubevirtNetwork removedNetwork,
1075 KubevirtRouter router,
Daniel Parkbabde9c2021-03-09 13:37:42 +09001076 KubevirtNode electedGw) {
Daniel Parkf3136042021-03-10 07:49:11 +09001077 router.internal().stream().filter(networkId -> kubevirtNetworkService.network(networkId) != null)
1078 .forEach(networkId -> {
1079 kubevirtPortService.ports(networkId).forEach(kubevirtPort -> {
1080 setGatewayInterNetworkRoutingFromNetworkToPort(
1081 router, removedNetwork, kubevirtPort, electedGw, false);
1082 });
Daniel Parkbabde9c2021-03-09 13:37:42 +09001083 });
Daniel Park2884b232021-03-04 18:58:47 +09001084 }
1085
1086 private void processRouterGatewayNodeAttached(KubevirtRouter router,
1087 String associatedGateway) {
1088 if (!isRelevantHelper()) {
1089 return;
1090 }
1091
1092 KubevirtNode gatewayNode = nodeService.node(associatedGateway);
1093 if (gatewayNode == null) {
1094 return;
1095 }
1096
1097 router.internal().forEach(networkName -> {
1098 KubevirtNetwork network = networkService.network(networkName);
1099
1100 if (network != null) {
1101 initGatewayNodeForInternalNetwork(network, router, gatewayNode, true);
1102 }
1103 });
1104 }
1105
1106 private void processRouterGatewayNodeDetached(KubevirtRouter router,
1107 String disAssociatedGateway) {
1108 if (!isRelevantHelper()) {
1109 return;
1110 }
1111
1112 KubevirtNode gatewayNode = nodeService.node(disAssociatedGateway);
1113 if (gatewayNode == null) {
1114 return;
1115 }
1116
1117 router.internal().forEach(networkName -> {
1118 KubevirtNetwork network = networkService.network(networkName);
1119
1120 if (network != null) {
1121 initGatewayNodeForInternalNetwork(network, router, gatewayNode, false);
1122 }
1123 });
1124 }
1125
1126 private void processRouterGatewayNodeChanged(KubevirtRouter router,
1127 String disAssociatedGateway) {
1128 if (!isRelevantHelper()) {
1129 return;
1130 }
1131
1132 KubevirtNode oldGatewayNode = nodeService.node(disAssociatedGateway);
1133 if (oldGatewayNode == null) {
1134 return;
1135 }
1136
1137 router.internal().forEach(networkName -> {
1138 KubevirtNetwork network = networkService.network(networkName);
1139
1140 if (network != null) {
1141 initGatewayNodeForInternalNetwork(network, router, oldGatewayNode, false);
1142 }
1143 });
1144
1145 KubevirtNode newGatewayNode = nodeService.node(router.electedGateway());
1146 if (newGatewayNode == null) {
1147 return;
1148 }
1149
1150 router.internal().forEach(networkName -> {
1151 KubevirtNetwork network = networkService.network(networkName);
1152
1153 if (network != null) {
1154 initGatewayNodeForInternalNetwork(network, router, oldGatewayNode, true);
1155 }
1156 });
1157 }
Daniel Parka8968802021-02-25 09:14:22 +09001158 }
1159
Jian Li556709c2021-02-03 17:54:28 +09001160 private class InternalNetworkEventListener implements KubevirtNetworkListener {
1161
1162 private boolean isRelevantHelper() {
1163 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1164 }
1165
1166 @Override
1167 public void event(KubevirtNetworkEvent event) {
1168 switch (event.type()) {
1169 case KUBEVIRT_NETWORK_CREATED:
1170 eventExecutor.execute(() -> processNetworkCreation(event.subject()));
1171 break;
1172 case KUBEVIRT_NETWORK_REMOVED:
1173 eventExecutor.execute(() -> processNetworkRemoval(event.subject()));
1174 break;
1175 case KUBEVIRT_NETWORK_UPDATED:
1176 default:
1177 // do nothing
1178 break;
1179 }
1180 }
1181
1182 private void processNetworkCreation(KubevirtNetwork network) {
1183 if (!isRelevantHelper()) {
1184 return;
1185 }
1186
1187 switch (network.type()) {
1188 case VXLAN:
1189 case GRE:
1190 case GENEVE:
1191 initIntegrationTunnelBridge(network);
1192 break;
1193 case FLAT:
Jian Li2ce718e2021-02-17 20:42:15 +09001194 case VLAN:
Daniel Parka8968802021-02-25 09:14:22 +09001195 break;
Jian Li556709c2021-02-03 17:54:28 +09001196 default:
1197 // do nothing
1198 break;
1199 }
1200 }
1201
1202 private void processNetworkRemoval(KubevirtNetwork network) {
1203 if (!isRelevantHelper()) {
1204 return;
1205 }
1206
1207 switch (network.type()) {
1208 case VXLAN:
1209 case GRE:
1210 case GENEVE:
1211 purgeIntegrationTunnelBridge(network);
1212 break;
1213 case FLAT:
Jian Li2ce718e2021-02-17 20:42:15 +09001214 case VLAN:
Daniel Parka8968802021-02-25 09:14:22 +09001215 break;
Jian Li556709c2021-02-03 17:54:28 +09001216 default:
1217 // do nothing
1218 break;
1219 }
1220 }
1221
1222 private void initIntegrationTunnelBridge(KubevirtNetwork network) {
1223 if (network.segmentId() == null) {
1224 return;
1225 }
1226
Jian Li94b6d162021-04-15 17:09:11 +09001227 nodeService.completeNodes(WORKER).forEach(n -> {
Jian Li556709c2021-02-03 17:54:28 +09001228 createBridge(n, network);
Daniel Parkf3136042021-03-10 07:49:11 +09001229 createPatchTenantInterface(n, network);
1230 setDefaultRulesForTenantNetwork(n, network);
Jian Li556709c2021-02-03 17:54:28 +09001231 });
1232 }
1233
1234 private void purgeIntegrationTunnelBridge(KubevirtNetwork network) {
1235 if (network.segmentId() == null) {
1236 return;
1237 }
1238
Jian Li567b25c2021-05-27 15:17:59 +09001239 nodeService.completeNodes(WORKER).forEach(n -> {
Jian Liea1ead72021-05-28 11:00:07 +09001240 removeAllFlows(n, network);
Jian Li556709c2021-02-03 17:54:28 +09001241 removePatchInterface(n, network);
Jian Liea1ead72021-05-28 11:00:07 +09001242
1243 try {
1244 sleep(SLEEP_LARGE_MS);
1245 } catch (InterruptedException e) {
1246 log.error("Sleep exception", e);
1247 }
1248
Jian Li556709c2021-02-03 17:54:28 +09001249 removeBridge(n, network);
1250 });
1251 }
1252 }
1253
1254 private class InternalNodeEventListener implements KubevirtNodeListener {
1255
1256 private boolean isRelevantHelper() {
1257 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1258 }
1259
1260 @Override
1261 public void event(KubevirtNodeEvent event) {
1262 switch (event.type()) {
1263 case KUBEVIRT_NODE_COMPLETE:
1264 eventExecutor.execute(() -> processNodeCompletion(event.subject()));
1265 break;
Daniel Park2884b232021-03-04 18:58:47 +09001266 case KUBEVIRT_NODE_REMOVED:
1267 eventExecutor.execute(() -> processNodeDeletion(event.subject()));
1268 break;
Jian Li556709c2021-02-03 17:54:28 +09001269 case KUBEVIRT_NODE_INCOMPLETE:
1270 case KUBEVIRT_NODE_UPDATED:
1271 default:
1272 // do nothing
1273 break;
1274 }
1275 }
1276
1277 private void processNodeCompletion(KubevirtNode node) {
1278 if (!isRelevantHelper()) {
1279 return;
1280 }
1281
Daniel Parka8968802021-02-25 09:14:22 +09001282 if (node.type().equals(WORKER)) {
1283 for (KubevirtNetwork network : networkService.networks()) {
1284 switch (network.type()) {
1285 case VXLAN:
1286 case GRE:
1287 case GENEVE:
1288 if (network.segmentId() == null) {
1289 continue;
1290 }
1291 createBridge(node, network);
Daniel Parkf3136042021-03-10 07:49:11 +09001292 createPatchTenantInterface(node, network);
1293 setDefaultRulesForTenantNetwork(node, network);
Jian Li8f944d42021-03-23 00:43:29 +09001294 setGatewayArpRulesForTenantNetwork(node, network);
1295 setGatewayIcmpRulesForTenantNetwork(node, network);
1296 setGatewayRuleToWorkerNodeWhenNodeCreated(node, network);
Daniel Parka8968802021-02-25 09:14:22 +09001297 break;
1298 case FLAT:
1299 case VLAN:
1300 default:
1301 // do nothing
1302 break;
1303 }
1304 }
1305 } else if (node.type().equals(GATEWAY)) {
Daniel Park2884b232021-03-04 18:58:47 +09001306 updateGatewayNodeForRouter();
Daniel Parka8968802021-02-25 09:14:22 +09001307 for (KubevirtNetwork network : networkService.networks()) {
1308 switch (network.type()) {
1309 case FLAT:
1310 case VLAN:
Daniel Parka8968802021-02-25 09:14:22 +09001311 break;
1312 case VXLAN:
1313 case GRE:
1314 case GENEVE:
1315 default:
1316 // do nothing
1317 break;
1318 }
Jian Li556709c2021-02-03 17:54:28 +09001319 }
1320 }
1321 }
Daniel Park2884b232021-03-04 18:58:47 +09001322
1323 private void processNodeDeletion(KubevirtNode node) {
1324 if (!isRelevantHelper()) {
1325 return;
1326 }
1327
1328 if (node.type().equals(GATEWAY)) {
1329 updateGatewayNodeForRouter();
1330 for (KubevirtNetwork network : networkService.networks()) {
1331 switch (network.type()) {
1332 case FLAT:
1333 case VLAN:
1334 break;
1335 case VXLAN:
1336 case GRE:
1337 case GENEVE:
1338 default:
1339 // do nothing
1340 break;
1341 }
1342 }
1343 }
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 }
1458
1459 }
1460 }
Jian Li556709c2021-02-03 17:54:28 +09001461}