blob: 992f2f424c9951570666870736b56bf33c10375e [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;
Jian Li0c656f02021-06-07 13:32:39 +090055import org.onosproject.net.Port;
Jian Li556709c2021-02-03 17:54:28 +090056import org.onosproject.net.PortNumber;
57import org.onosproject.net.behaviour.BridgeConfig;
58import org.onosproject.net.behaviour.BridgeDescription;
59import org.onosproject.net.behaviour.BridgeName;
60import org.onosproject.net.behaviour.ControllerInfo;
61import org.onosproject.net.behaviour.DefaultBridgeDescription;
62import org.onosproject.net.behaviour.DefaultPatchDescription;
63import org.onosproject.net.behaviour.InterfaceConfig;
64import org.onosproject.net.behaviour.PatchDescription;
65import org.onosproject.net.device.DeviceAdminService;
Daniel Parka8968802021-02-25 09:14:22 +090066import org.onosproject.net.driver.DriverService;
Jian Li556709c2021-02-03 17:54:28 +090067import org.onosproject.net.flow.DefaultTrafficSelector;
68import org.onosproject.net.flow.DefaultTrafficTreatment;
69import org.onosproject.net.flow.TrafficSelector;
70import org.onosproject.net.flow.TrafficTreatment;
71import org.osgi.service.component.annotations.Activate;
72import org.osgi.service.component.annotations.Component;
73import org.osgi.service.component.annotations.Deactivate;
74import org.osgi.service.component.annotations.Reference;
75import org.osgi.service.component.annotations.ReferenceCardinality;
76import org.slf4j.Logger;
77
78import java.util.List;
79import java.util.Objects;
Daniel Park2884b232021-03-04 18:58:47 +090080import java.util.Set;
Jian Li556709c2021-02-03 17:54:28 +090081import java.util.concurrent.ExecutorService;
82
Jian Li556709c2021-02-03 17:54:28 +090083import 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 Li0c656f02021-06-07 13:32:39 +0900121import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.waitFor;
Jian Li858ccd72021-02-04 17:25:01 +0900122import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.NXM_NX_IP_TTL;
123import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.NXM_OF_ICMP_TYPE;
Daniel Parkf3136042021-03-10 07:49:11 +0900124import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildExtension;
Jian Li858ccd72021-02-04 17:25:01 +0900125import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildLoadExtension;
126import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveArpShaToThaExtension;
127import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveArpSpaToTpaExtension;
128import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveEthSrcToDstExtension;
129import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveIpSrcToDstExtension;
Jian Li556709c2021-02-03 17:54:28 +0900130import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_BRIDGE;
Daniel Parkf3136042021-03-10 07:49:11 +0900131import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_TO_INTEGRATION;
Daniel Parka8968802021-02-25 09:14:22 +0900132import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
133import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.WORKER;
Jian Li0c656f02021-06-07 13:32:39 +0900134import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Jian Li556709c2021-02-03 17:54:28 +0900135import static org.slf4j.LoggerFactory.getLogger;
136
137/**
138 * Handles kubevirt network events.
139 */
140@Component(immediate = true)
141public class KubevirtNetworkHandler {
142 protected final Logger log = getLogger(getClass());
143 private static final String DEFAULT_OF_PROTO = "tcp";
144 private static final int DEFAULT_OFPORT = 6653;
145 private static final int DPID_BEGIN = 3;
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()));
Jian Li7db46722021-06-14 21:28:31 +0900229 if (tenantBridge != null && deviceService.isAvailable(tenantBridge.id())) {
Jian Li8f944d42021-03-23 00:43:29 +0900230 log.warn("The tenant bridge {} already exists at node {}",
Jian Li556709c2021-02-03 17:54:28 +0900231 network.tenantBridgeName(), node.hostname());
Jian Li556709c2021-02-03 17:54:28 +0900232 return;
233 }
234
235 Device device = deviceService.getDevice(node.ovsdb());
236
Jian Li94b6d162021-04-15 17:09:11 +0900237 IpAddress serverIp;
238 String serviceFqdn = apiConfigService.apiConfig().serviceFqdn();
239 IpAddress serviceIp = null;
240
241 if (serviceFqdn != null) {
242 serviceIp = resolveHostname(serviceFqdn);
243 }
244
245 if (serviceIp != null) {
246 serverIp = serviceIp;
247 } else {
248 serverIp = apiConfigService.apiConfig().ipAddress();
249 }
250
Jian Li556709c2021-02-03 17:54:28 +0900251 ControllerInfo controlInfo =
252 new ControllerInfo(serverIp, DEFAULT_OFPORT, DEFAULT_OF_PROTO);
253 List<ControllerInfo> controllers = Lists.newArrayList(controlInfo);
254
255 String dpid = network.tenantDeviceId(
256 node.hostname()).toString().substring(DPID_BEGIN);
257
Jian Li0c656f02021-06-07 13:32:39 +0900258 // if the bridge is already available, we skip creating a new bridge
259 if (!deviceService.isAvailable(DeviceId.deviceId(dpid))) {
260 BridgeDescription.Builder builder = DefaultBridgeDescription.builder()
261 .name(network.tenantBridgeName())
262 .failMode(BridgeDescription.FailMode.SECURE)
263 .datapathId(dpid)
264 .disableInBand()
265 .controllers(controllers);
Jian Li556709c2021-02-03 17:54:28 +0900266
Jian Li0c656f02021-06-07 13:32:39 +0900267 BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
268 bridgeConfig.addBridge(builder.build());
269
Jian Li7db46722021-06-14 21:28:31 +0900270 log.info("Created a new tunnel bridge for network {} at node {}",
271 network.networkId(), node.hostname());
272
Jian Li0c656f02021-06-07 13:32:39 +0900273 waitFor(3);
274 }
Jian Li556709c2021-02-03 17:54:28 +0900275 }
276
277 private void removeBridge(KubevirtNode node, KubevirtNetwork network) {
278 Device device = deviceService.getDevice(node.ovsdb());
279
280 BridgeName bridgeName = BridgeName.bridgeName(network.tenantBridgeName());
281
282 BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
283 bridgeConfig.deleteBridge(bridgeName);
284 deviceService.removeDevice(network.tenantDeviceId(node.hostname()));
285 }
286
Daniel Parkf3136042021-03-10 07:49:11 +0900287 private void createPatchTenantInterface(KubevirtNode node, KubevirtNetwork network) {
Jian Li556709c2021-02-03 17:54:28 +0900288 Device device = deviceService.getDevice(node.ovsdb());
289
290 if (device == null || !device.is(InterfaceConfig.class)) {
291 log.error("Failed to create patch interface on {}", node.ovsdb());
292 return;
293 }
294
295 InterfaceConfig ifaceConfig = device.as(InterfaceConfig.class);
296
Jian Li858ccd72021-02-04 17:25:01 +0900297 String tenantToTunIntf =
298 TENANT_TO_TUNNEL_PREFIX + segmentIdHex(network.segmentId());
299 String tunToTenantIntf =
300 TUNNEL_TO_TENANT_PREFIX + segmentIdHex(network.segmentId());
Jian Li556709c2021-02-03 17:54:28 +0900301
Jian Lif3a3c5a2021-06-30 10:21:31 +0900302 if (!hasPort(network.tenantDeviceId(node.hostname()), tenantToTunIntf)) {
303 // patch ports for tenant bridge -> tunnel bridge
Jian Li0c656f02021-06-07 13:32:39 +0900304 PatchDescription brTenantTunPatchDesc =
305 DefaultPatchDescription.builder()
306 .deviceId(network.tenantBridgeName())
307 .ifaceName(tenantToTunIntf)
308 .peer(tunToTenantIntf)
309 .build();
Jian Li556709c2021-02-03 17:54:28 +0900310
Jian Li0c656f02021-06-07 13:32:39 +0900311 ifaceConfig.addPatchMode(tenantToTunIntf, brTenantTunPatchDesc);
Jian Li556709c2021-02-03 17:54:28 +0900312
Jian Li0c656f02021-06-07 13:32:39 +0900313 waitFor(1);
314 }
315
Jian Lif3a3c5a2021-06-30 10:21:31 +0900316 if (!hasPort(node.tunBridge(), tunToTenantIntf)) {
Jian Li0c656f02021-06-07 13:32:39 +0900317 // tunnel bridge -> tenant bridge
318 PatchDescription brTunTenantPatchDesc =
319 DefaultPatchDescription.builder()
320 .deviceId(TUNNEL_BRIDGE)
321 .ifaceName(tunToTenantIntf)
322 .peer(tenantToTunIntf)
323 .build();
324 ifaceConfig.addPatchMode(tunToTenantIntf, brTunTenantPatchDesc);
325
326 waitFor(1);
327 }
Jian Li556709c2021-02-03 17:54:28 +0900328 }
329
Jian Liea1ead72021-05-28 11:00:07 +0900330 private void removeAllFlows(KubevirtNode node, KubevirtNetwork network) {
331 DeviceId deviceId = network.tenantDeviceId(node.hostname());
332 flowService.purgeRules(deviceId);
333 }
334
Jian Li556709c2021-02-03 17:54:28 +0900335 private void removePatchInterface(KubevirtNode node, KubevirtNetwork network) {
336 Device device = deviceService.getDevice(node.ovsdb());
337
338 if (device == null || !device.is(InterfaceConfig.class)) {
339 log.error("Failed to create patch interface on {}", node.ovsdb());
340 return;
341 }
342
343 InterfaceConfig ifaceConfig = device.as(InterfaceConfig.class);
344
Jian Li858ccd72021-02-04 17:25:01 +0900345 String tunToIntIntf = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(network.segmentId());
Jian Li556709c2021-02-03 17:54:28 +0900346
347 ifaceConfig.removePatchMode(tunToIntIntf);
348 }
349
Jian Li8f944d42021-03-23 00:43:29 +0900350 private void setGatewayArpRulesForTenantNetwork(KubevirtNode node,
351 KubevirtNetwork network) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900352
353 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
354 if (router == null) {
355 return;
356 }
357
358 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
359 if (electedGw == null) {
360 return;
361 }
362
Jian Li8f944d42021-03-23 00:43:29 +0900363 setGatewayArpRuleForTenantInternalNetwork(router, network, TENANT_ARP_TABLE,
364 electedGw.intgBridge(), network.tenantDeviceId(node.hostname()), true);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900365 }
366
Jian Li8f944d42021-03-23 00:43:29 +0900367 private void setGatewayIcmpRulesForTenantNetwork(KubevirtNode node,
368 KubevirtNetwork network) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900369 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
370 if (router == null) {
371 return;
372 }
373
374 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
375 if (electedGw == null) {
376 return;
377 }
378
Jian Li8f944d42021-03-23 00:43:29 +0900379 setGatewayIcmpRuleForTenantInternalNetwork(router, network, TENANT_ICMP_TABLE,
380 electedGw.intgBridge(), network.tenantDeviceId(node.hostname()), true);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900381 }
382
Jian Li8f944d42021-03-23 00:43:29 +0900383 private void setGatewayRuleToWorkerNodeWhenNodeCreated(KubevirtNode node,
384 KubevirtNetwork network) {
Daniel Parkf3136042021-03-10 07:49:11 +0900385 KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
386 if (router == null) {
387 return;
388 }
Daniel Parkbabde9c2021-03-09 13:37:42 +0900389
Daniel Parkf3136042021-03-10 07:49:11 +0900390 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
391 if (electedGw == null) {
392 return;
393 }
394
Jian Li8f944d42021-03-23 00:43:29 +0900395 setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
396 electedGw.intgBridge(), node, true);
Daniel Parkf3136042021-03-10 07:49:11 +0900397 }
398
Jian Li8f944d42021-03-23 00:43:29 +0900399 private void setDefaultRulesForTenantNetwork(KubevirtNode node,
400 KubevirtNetwork network) {
Jian Li556709c2021-02-03 17:54:28 +0900401 DeviceId deviceId = network.tenantDeviceId(node.hostname());
402
403 while (!deviceService.isAvailable(deviceId)) {
404 log.warn("Device {} is not ready for installing rules", deviceId);
Jian Li0c656f02021-06-07 13:32:39 +0900405 waitFor(3);
Jian Li556709c2021-02-03 17:54:28 +0900406 }
407
408 flowService.connectTables(deviceId, TENANT_INBOUND_TABLE, TENANT_DHCP_TABLE);
Jian Li858ccd72021-02-04 17:25:01 +0900409 flowService.connectTables(deviceId, TENANT_DHCP_TABLE, TENANT_ARP_TABLE);
410 flowService.connectTables(deviceId, TENANT_ARP_TABLE, TENANT_ICMP_TABLE);
411 flowService.connectTables(deviceId, TENANT_ICMP_TABLE, TENANT_FORWARDING_TABLE);
Jian Li556709c2021-02-03 17:54:28 +0900412
Jian Li8f944d42021-03-23 00:43:29 +0900413 setArpRuleForTenantNetwork(deviceId, true);
Daniel Parkf3136042021-03-10 07:49:11 +0900414 setDhcpRuleForTenantNetwork(deviceId, true);
Jian Li556709c2021-02-03 17:54:28 +0900415 setForwardingRule(deviceId, true);
416
Jian Li8f944d42021-03-23 00:43:29 +0900417 // security group related rules
418 setTenantIngressTransitionRule(network, network.tenantDeviceId(node.hostname()), true);
Jian Lif89d9602021-04-27 19:05:49 +0900419 setTenantEgressTransitionRule(network.tenantDeviceId(node.hostname()), true);
Jian Li8f944d42021-03-23 00:43:29 +0900420
Jian Li556709c2021-02-03 17:54:28 +0900421 log.info("Install default flow rules for tenant bridge {}", network.tenantBridgeName());
422 }
423
Daniel Parkf3136042021-03-10 07:49:11 +0900424 private void setDhcpRuleForTenantNetwork(DeviceId deviceId, boolean install) {
Jian Li556709c2021-02-03 17:54:28 +0900425 TrafficSelector selector = DefaultTrafficSelector.builder()
426 .matchEthType(Ethernet.TYPE_IPV4)
427 .matchIPProtocol(IPv4.PROTOCOL_UDP)
428 .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
429 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
430 .build();
431
432 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
433 .punt()
434 .build();
435
436 flowService.setRule(
437 appId,
438 deviceId,
439 selector,
440 treatment,
441 PRIORITY_DHCP_RULE,
442 TENANT_DHCP_TABLE,
443 install);
444 }
445
Jian Li858ccd72021-02-04 17:25:01 +0900446 private void setForwardingRule(DeviceId deviceId, boolean install) {
Jian Li556709c2021-02-03 17:54:28 +0900447 TrafficSelector selector = DefaultTrafficSelector.builder().build();
448 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
449 .setOutput(PortNumber.NORMAL)
450 .build();
451
452 flowService.setRule(
453 appId,
454 deviceId,
455 selector,
456 treatment,
Jian Li858ccd72021-02-04 17:25:01 +0900457 PRIORITY_FORWARDING_RULE,
Jian Li556709c2021-02-03 17:54:28 +0900458 TENANT_FORWARDING_TABLE,
459 install);
460 }
461
Daniel Park2884b232021-03-04 18:58:47 +0900462 private void initGatewayNodeForInternalNetwork(KubevirtNetwork network,
463 KubevirtRouter router,
464 KubevirtNode electedGateway,
465 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900466 switch (network.type()) {
467 case VXLAN:
468 case GRE:
469 case GENEVE:
Jian Li8f944d42021-03-23 00:43:29 +0900470 setDefaultEgressRuleToGatewayNode(router, network,
471 electedGateway.intgBridge(), install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900472 kubevirtNodeService.completeNodes(WORKER).forEach(node -> {
Jian Li8f944d42021-03-23 00:43:29 +0900473 setGatewayArpRuleForTenantInternalNetwork(router, network,
474 TENANT_ARP_TABLE, electedGateway.intgBridge(),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900475 network.tenantDeviceId(node.hostname()), install);
Jian Li8f944d42021-03-23 00:43:29 +0900476 setGatewayIcmpRuleForTenantInternalNetwork(router, network,
477 TENANT_ICMP_TABLE, electedGateway.intgBridge(),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900478 network.tenantDeviceId(node.hostname()), install);
Jian Li517597a2021-03-22 11:04:52 +0900479 setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
Daniel Parkf3136042021-03-10 07:49:11 +0900480 electedGateway.intgBridge(), node, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900481 });
Daniel Park4cb120b2021-03-24 12:30:50 +0900482 setGatewayProviderInterNetworkRoutingWithinSameRouter(network, router, electedGateway, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900483 break;
484 case FLAT:
485 case VLAN:
Jian Li8f944d42021-03-23 00:43:29 +0900486 setGatewayArpRuleForProviderInternalNetwork(router, network,
Jian Lif89d9602021-04-27 19:05:49 +0900487 GW_ENTRY_TABLE, electedGateway.intgBridge(), install);
Jian Li8f944d42021-03-23 00:43:29 +0900488 setGatewayIcmpRuleForProviderInternalNetwork(router, network,
Jian Lif89d9602021-04-27 19:05:49 +0900489 GW_ENTRY_TABLE, electedGateway.intgBridge(), install);
Jian Li8f944d42021-03-23 00:43:29 +0900490 setGatewayProviderInterNetworkRoutingWithinSameRouter(network,
491 router, electedGateway, install);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900492 break;
493 default:
494 // do nothing
495 break;
496 }
Daniel Park2884b232021-03-04 18:58:47 +0900497 }
498
Jian Li517597a2021-03-22 11:04:52 +0900499 private void setDefaultGatewayRuleToWorkerNodeTunBridge(KubevirtRouter router,
500 KubevirtNetwork network,
501 DeviceId gwDeviceId,
502 KubevirtNode workerNode,
503 boolean install) {
Daniel Parkf3136042021-03-10 07:49:11 +0900504 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900505
Daniel Parkf3136042021-03-10 07:49:11 +0900506 if (routerMacAddress == null) {
Jian Li34fff802021-07-01 10:04:04 +0900507 log.warn("Setting gateway default egress rule to gateway for tenant " +
508 "internal network because there's no br-int port for device {}", gwDeviceId);
Daniel Parkf3136042021-03-10 07:49:11 +0900509 return;
510 }
511
512 KubevirtNode gwNode = kubevirtNodeService.node(gwDeviceId);
513
514 if (gwNode == null) {
Jian Li34fff802021-07-01 10:04:04 +0900515 log.warn("Setting gateway default egress rule to gateway for tenant " +
516 "internal network because there's no gateway node for device {}", gwDeviceId);
Daniel Parkf3136042021-03-10 07:49:11 +0900517 return;
518 }
519
Jian Li34fff802021-07-01 10:04:04 +0900520 PortNumber patchPortNumber = tunnelToTenantPort(deviceService, workerNode, network);
Daniel Parkf3136042021-03-10 07:49:11 +0900521 if (patchPortNumber == null) {
522 return;
523 }
524
525 PortNumber tunnelPortNumber = tunnelPort(workerNode, network);
526 if (tunnelPortNumber == null) {
527 return;
528 }
529
530 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
531 .matchInPort(patchPortNumber)
532 .matchEthType(Ethernet.TYPE_IPV4)
533 .matchEthDst((routerMacAddress));
534
535 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
536 .setTunnelId(Long.parseLong(network.segmentId()))
537 .extension(buildExtension(
538 deviceService,
539 workerNode.tunBridge(),
540 gwNode.dataIp().getIp4Address()),
541 workerNode.tunBridge())
542 .setOutput(tunnelPortNumber);
543
544 flowService.setRule(
545 appId,
546 workerNode.tunBridge(),
547 sBuilder.build(),
548 tBuilder.build(),
549 PRIORITY_FORWARDING_RULE,
550 TUNNEL_DEFAULT_TABLE,
551 install);
552 }
553
Jian Li8f944d42021-03-23 00:43:29 +0900554 private void setTenantIngressTransitionRule(KubevirtNetwork network,
555 DeviceId deviceId, boolean install) {
556 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
557 sBuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort())
558 .matchInPort(network.tenantToTunnelPort(deviceId));
559
560 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
561 tBuilder.transition(TENANT_ACL_INGRESS_TABLE);
562
563 flowService.setRule(appId,
564 deviceId,
565 sBuilder.build(),
566 tBuilder.build(),
567 PRIORITY_IP_INGRESS_RULE,
568 TENANT_ICMP_TABLE,
569 install
570 );
571 }
572
Jian Lif89d9602021-04-27 19:05:49 +0900573 private void setTenantEgressTransitionRule(DeviceId deviceId, boolean install) {
Jian Li8f944d42021-03-23 00:43:29 +0900574 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
575 sBuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort());
576
577 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
578 tBuilder.transition(TENANT_ACL_EGRESS_TABLE);
579
580 flowService.setRule(appId,
581 deviceId,
582 sBuilder.build(),
583 tBuilder.build(),
584 PRIORITY_IP_EGRESS_RULE,
585 TENANT_ICMP_TABLE,
586 install
587 );
588 }
589
Daniel Parkf3136042021-03-10 07:49:11 +0900590 private void setDefaultEgressRuleToGatewayNode(KubevirtRouter router,
591 KubevirtNetwork network,
592 DeviceId gwDeviceId,
593 boolean install) {
594 MacAddress routerMacAddress = getRouterMacAddress(router);
595
596 if (routerMacAddress == null) {
597 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
598 "there's no br-int port for device {}", gwDeviceId);
599 return;
600 }
601
602 KubevirtNode gwNode = kubevirtNodeService.node(gwDeviceId);
603
604 if (gwNode == null) {
605 log.warn("Setting gateway default eggress rule to gateway for tenant internal network because " +
606 "there's no gateway node for device {}", gwDeviceId);
607 return;
608 }
609
Jian Li34fff802021-07-01 10:04:04 +0900610 PortNumber tunToIntPortNum = portNumber(deviceService, gwNode.tunBridge(), TUNNEL_TO_INTEGRATION);
Daniel Parkf3136042021-03-10 07:49:11 +0900611
612 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
613 .matchTunnelId(Long.parseLong(network.segmentId()));
614
615 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
616 .setOutput(tunToIntPortNum);
617
618 flowService.setRule(
619 appId,
620 gwNode.tunBridge(),
621 sBuilder.build(),
622 tBuilder.build(),
623 PRIORITY_TUNNEL_RULE,
624 TUNNEL_DEFAULT_TABLE,
625 install);
626 }
627
628
629 private void setGatewayIcmpRuleForTenantInternalNetwork(KubevirtRouter router,
630 KubevirtNetwork network,
631 int tableNum,
632 DeviceId gwDeviceId,
633 DeviceId tenantDeviceId,
634 boolean install) {
635 MacAddress routerMacAddress = getRouterMacAddress(router);
636
637 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900638 log.warn("Setting gateway ICMP rule for internal network because " +
639 "there's no br-int port for device {}", gwDeviceId);
640 return;
641 }
642
643 Device device = deviceService.getDevice(tenantDeviceId);
644
645 if (device == null) {
646 log.warn("Setting gateway icmp rule for internal network because " +
647 "there's no tenant device for {} to install gateway arp rule",
648 tenantDeviceId);
649 return;
650 }
651
Daniel Parkbabde9c2021-03-09 13:37:42 +0900652 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
653 .matchEthType(Ethernet.TYPE_IPV4)
654 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
655 .matchIcmpType(TYPE_ECHO_REQUEST)
656 .matchIcmpCode(CODE_ECHO_REQEUST)
657 .matchIPDst(IpPrefix.valueOf(network.gatewayIp(), 32));
658
659 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
660 .extension(buildMoveEthSrcToDstExtension(device), device.id())
661 .extension(buildMoveIpSrcToDstExtension(device), device.id())
662 .extension(buildLoadExtension(device,
663 NXM_NX_IP_TTL, DEFAULT_TTL), device.id())
664 .extension(buildLoadExtension(device,
665 NXM_OF_ICMP_TYPE, TYPE_ECHO_REPLY), device.id())
666 .setIpSrc(network.gatewayIp())
Daniel Parkf3136042021-03-10 07:49:11 +0900667 .setEthSrc(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900668 .setOutput(PortNumber.IN_PORT);
669
670 flowService.setRule(
671 appId,
672 tenantDeviceId,
673 sBuilder.build(),
674 tBuilder.build(),
675 PRIORITY_ICMP_RULE,
676 tableNum,
677 install);
678 }
679
Jian Li8f944d42021-03-23 00:43:29 +0900680 private void setArpRuleForTenantNetwork(DeviceId tenantDeviceId,
681 boolean install) {
682 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
683 .matchEthType(EthType.EtherType.ARP.ethType().toShort());
684
685 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
686 .transition(TENANT_FORWARDING_TABLE);
687
688 flowService.setRule(
689 appId,
690 tenantDeviceId,
691 sBuilder.build(),
692 tBuilder.build(),
693 PRIORITY_ARP_DEFAULT_RULE,
694 TENANT_ARP_TABLE,
695 install
696 );
697 }
698
Daniel Parkf3136042021-03-10 07:49:11 +0900699 private void setGatewayArpRuleForTenantInternalNetwork(KubevirtRouter router,
700 KubevirtNetwork network,
701 int tableNum,
702 DeviceId gwDeviceId,
703 DeviceId tenantDeviceId,
704 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900705
Daniel Parkf3136042021-03-10 07:49:11 +0900706 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900707
Daniel Parkf3136042021-03-10 07:49:11 +0900708 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900709 log.warn("Setting gateway arp rule for internal network because " +
710 "there's no br-int port for device {}", gwDeviceId);
711 return;
712 }
713
714 Device device = deviceService.getDevice(tenantDeviceId);
715
716 if (device == null) {
717 log.warn("Setting gateway arp rule for internal network because " +
718 "there's no tenant device for {} to install gateway arp rule",
719 tenantDeviceId);
720 return;
721 }
722
723
724 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
725 sBuilder.matchEthType(EthType.EtherType.ARP.ethType().toShort())
726 .matchArpOp(ARP.OP_REQUEST)
727 .matchArpTpa(Ip4Address.valueOf(network.gatewayIp().toString()));
728
729 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
730 tBuilder.extension(buildMoveEthSrcToDstExtension(device), device.id())
731 .extension(buildMoveArpShaToThaExtension(device), device.id())
732 .extension(buildMoveArpSpaToTpaExtension(device), device.id())
733 .setArpOp(ARP.OP_REPLY)
Daniel Parkf3136042021-03-10 07:49:11 +0900734 .setArpSha(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900735 .setArpSpa(Ip4Address.valueOf(network.gatewayIp().toString()))
Daniel Parkf3136042021-03-10 07:49:11 +0900736 .setEthSrc(routerMacAddress)
Daniel Parkbabde9c2021-03-09 13:37:42 +0900737 .setOutput(PortNumber.IN_PORT);
738
739 flowService.setRule(
740 appId,
741 device.id(),
742 sBuilder.build(),
743 tBuilder.build(),
744 PRIORITY_ARP_GATEWAY_RULE,
745 tableNum,
746 install
747 );
748 }
749
Daniel Parkf3136042021-03-10 07:49:11 +0900750 private void setGatewayProviderInterNetworkRoutingWithinSameRouter(
Daniel Parkbabde9c2021-03-09 13:37:42 +0900751 KubevirtNetwork network, KubevirtRouter router, KubevirtNode gatewayNode, boolean install) {
Daniel Park2884b232021-03-04 18:58:47 +0900752 router.internal().forEach(srcNetwork -> {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900753 if (srcNetwork.equals(network.networkId())
754 || kubevirtNetworkService.network(srcNetwork) == null) {
Daniel Park2884b232021-03-04 18:58:47 +0900755 return;
756 }
757
Daniel Parkbabde9c2021-03-09 13:37:42 +0900758 kubevirtPortService.ports(network.networkId()).forEach(port -> {
Daniel Parkf3136042021-03-10 07:49:11 +0900759 setGatewayInterNetworkRoutingFromNetworkToPort(router, kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +0900760 port, gatewayNode, install);
761 });
Daniel Park2884b232021-03-04 18:58:47 +0900762 });
763 }
764
Daniel Parkf3136042021-03-10 07:49:11 +0900765 private void setGatewayInterNetworkRoutingFromNetworkToPort(KubevirtRouter router,
766 KubevirtNetwork srcNetwork,
767 KubevirtPort dstPort,
768 KubevirtNode gatewayNode,
769 boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900770 Device gwDevice = deviceService.getDevice(gatewayNode.intgBridge());
771
772 if (gwDevice == null) {
773 log.warn("Failed to set internal network routing rule because " +
774 "there's no device Id for device {}", gatewayNode.intgBridge());
775 return;
776 }
777
Daniel Parkf3136042021-03-10 07:49:11 +0900778 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900779
Daniel Parkf3136042021-03-10 07:49:11 +0900780 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900781 log.warn("Failed to set internal network routing rule because " +
782 "there's no br-int port for device {}", gatewayNode.intgBridge());
783 return;
784 }
785
Daniel Park4cb120b2021-03-24 12:30:50 +0900786 TrafficSelector.Builder sBuilder;
787 TrafficTreatment treatment;
Daniel Parkbabde9c2021-03-09 13:37:42 +0900788
Daniel Park4cb120b2021-03-24 12:30:50 +0900789 if (srcNetwork.type() == FLAT || srcNetwork.type() == VLAN) {
790 sBuilder = DefaultTrafficSelector.builder()
791 .matchEthType(Ethernet.TYPE_IPV4)
792 .matchEthDst(routerMacAddress)
793 .matchIPSrc(IpPrefix.valueOf(srcNetwork.cidr()))
794 .matchIPDst(IpPrefix.valueOf(dstPort.ipAddress(), 32));
Daniel Parkbabde9c2021-03-09 13:37:42 +0900795
Daniel Park4cb120b2021-03-24 12:30:50 +0900796 treatment = DefaultTrafficTreatment.builder()
797 .setEthSrc(routerMacAddress)
798 .setEthDst(dstPort.macAddress())
799 .transition(FORWARDING_TABLE)
800 .build();
801
802 flowService.setRule(
803 appId,
804 gwDevice.id(),
805 sBuilder.build(),
806 treatment,
807 PRIORITY_INTERNAL_ROUTING_RULE,
Jian Lif89d9602021-04-27 19:05:49 +0900808 GW_ENTRY_TABLE,
Daniel Park4cb120b2021-03-24 12:30:50 +0900809 install);
810 } else {
811 KubevirtNetwork dstNetwork = kubevirtNetworkService.network(dstPort.networkId());
812 if (dstNetwork == null) {
813 return;
814 }
815
816 KubevirtNode dstPortWorkerNode = kubevirtNodeService.node(dstPort.deviceId());
817 if (dstPortWorkerNode == null) {
818 return;
819 }
820
821 sBuilder = DefaultTrafficSelector.builder()
822 .matchEthType(Ethernet.TYPE_IPV4)
823 .matchEthDst(routerMacAddress)
824 .matchTunnelId(Long.parseLong(srcNetwork.segmentId()))
825 .matchIPSrc(IpPrefix.valueOf(srcNetwork.cidr()))
826 .matchIPDst(IpPrefix.valueOf(dstPort.ipAddress(), 32));
827
828 treatment = DefaultTrafficTreatment.builder()
829 .setTunnelId(Long.parseLong(dstNetwork.segmentId()))
830 .setEthSrc(routerMacAddress)
831 .setEthDst(dstPort.macAddress())
832 .extension(buildExtension(
833 deviceService,
834 gatewayNode.tunBridge(),
835 dstPortWorkerNode.dataIp().getIp4Address()),
836 gatewayNode.tunBridge())
837 .setOutput(PortNumber.IN_PORT)
838 .build();
839
840 flowService.setRule(
841 appId,
842 gatewayNode.tunBridge(),
843 sBuilder.build(),
844 treatment,
845 PRIORITY_INTERNAL_ROUTING_RULE,
846 TUNNEL_DEFAULT_TABLE,
847 install);
848 }
Daniel Parkbabde9c2021-03-09 13:37:42 +0900849 }
850
Daniel Parkf3136042021-03-10 07:49:11 +0900851 private void setGatewayArpRuleForProviderInternalNetwork(KubevirtRouter router, KubevirtNetwork network,
852 int tableNum, DeviceId gwDeviceId, boolean install) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900853
854
855 Device device = deviceService.getDevice(gwDeviceId);
Daniel Parkf3136042021-03-10 07:49:11 +0900856 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Parkbabde9c2021-03-09 13:37:42 +0900857
Daniel Parkf3136042021-03-10 07:49:11 +0900858 if (routerMacAddress == null) {
Daniel Parkbabde9c2021-03-09 13:37:42 +0900859 log.warn("Setting gateway arp rule for internal network because " +
860 "there's no br-int port for device {}", gwDeviceId);
Daniel Park2884b232021-03-04 18:58:47 +0900861 return;
862 }
863
Jian Li858ccd72021-02-04 17:25:01 +0900864 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
865 sBuilder.matchEthType(EthType.EtherType.ARP.ethType().toShort())
866 .matchArpOp(ARP.OP_REQUEST)
867 .matchArpTpa(Ip4Address.valueOf(network.gatewayIp().toString()));
868
869 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
870 tBuilder.extension(buildMoveEthSrcToDstExtension(device), device.id())
871 .extension(buildMoveArpShaToThaExtension(device), device.id())
872 .extension(buildMoveArpSpaToTpaExtension(device), device.id())
873 .setArpOp(ARP.OP_REPLY)
Daniel Parkf3136042021-03-10 07:49:11 +0900874 .setArpSha(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900875 .setArpSpa(Ip4Address.valueOf(network.gatewayIp().toString()))
Daniel Parkf3136042021-03-10 07:49:11 +0900876 .setEthSrc(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900877 .setOutput(PortNumber.IN_PORT);
878
879 flowService.setRule(
880 appId,
881 device.id(),
882 sBuilder.build(),
883 tBuilder.build(),
884 PRIORITY_ARP_GATEWAY_RULE,
Daniel Parka8968802021-02-25 09:14:22 +0900885 tableNum,
Jian Li858ccd72021-02-04 17:25:01 +0900886 install
887 );
888 }
889
Daniel Park2884b232021-03-04 18:58:47 +0900890 /**
891 * Sends ICMP echo reply for the ICMP echo request from the kubevirt VM.
892 *
Daniel Parkf3136042021-03-10 07:49:11 +0900893 * @param router kubevirt router
Daniel Park2884b232021-03-04 18:58:47 +0900894 * @param network kubevirt network
895 * @param tableNum flow table number
896 * @param deviceId device id of the selected gateway for the network
897 * @param install install if true, remove otherwise
898 */
Daniel Parkf3136042021-03-10 07:49:11 +0900899 private void setGatewayIcmpRuleForProviderInternalNetwork(KubevirtRouter router, KubevirtNetwork network,
900 int tableNum, DeviceId deviceId, boolean install) {
901 MacAddress routerMacAddress = getRouterMacAddress(router);
Daniel Park2884b232021-03-04 18:58:47 +0900902
Daniel Parkf3136042021-03-10 07:49:11 +0900903 if (routerMacAddress == null) {
Daniel Park2884b232021-03-04 18:58:47 +0900904 log.error("Setting gateway ICMP rule for internal network because " +
905 "there's no br-int port for device {}", deviceId);
906 return;
907 }
908
Jian Li858ccd72021-02-04 17:25:01 +0900909 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
910 .matchEthType(Ethernet.TYPE_IPV4)
911 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
912 .matchIcmpType(TYPE_ECHO_REQUEST)
913 .matchIcmpCode(CODE_ECHO_REQEUST)
914 .matchIPDst(IpPrefix.valueOf(network.gatewayIp(), 32));
915
916 Device device = deviceService.getDevice(deviceId);
917 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
918 .extension(buildMoveEthSrcToDstExtension(device), device.id())
919 .extension(buildMoveIpSrcToDstExtension(device), device.id())
920 .extension(buildLoadExtension(device,
921 NXM_NX_IP_TTL, DEFAULT_TTL), device.id())
922 .extension(buildLoadExtension(device,
923 NXM_OF_ICMP_TYPE, TYPE_ECHO_REPLY), device.id())
924 .setIpSrc(network.gatewayIp())
Daniel Parkf3136042021-03-10 07:49:11 +0900925 .setEthSrc(routerMacAddress)
Jian Li858ccd72021-02-04 17:25:01 +0900926 .setOutput(PortNumber.IN_PORT);
927
928 flowService.setRule(
929 appId,
930 deviceId,
931 sBuilder.build(),
932 tBuilder.build(),
933 PRIORITY_ICMP_RULE,
Daniel Parka8968802021-02-25 09:14:22 +0900934 tableNum,
Jian Li858ccd72021-02-04 17:25:01 +0900935 install);
936 }
937
Jian Li0c656f02021-06-07 13:32:39 +0900938 private boolean hasPort(DeviceId deviceId, String portName) {
Jian Li0c656f02021-06-07 13:32:39 +0900939 Port port = deviceService.getPorts(deviceId).stream()
940 .filter(p -> p.isEnabled() &&
941 Objects.equals(p.annotations().value(PORT_NAME), portName))
942 .findAny().orElse(null);
Jian Lif3a3c5a2021-06-30 10:21:31 +0900943 log.info("The port {} already existed on device {}", portName, deviceId);
944
Jian Li0c656f02021-06-07 13:32:39 +0900945 return port != null;
946 }
947
Daniel Park2884b232021-03-04 18:58:47 +0900948 private class InternalRouterEventListener implements KubevirtRouterListener {
949 private boolean isRelevantHelper() {
950 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
Daniel Parka8968802021-02-25 09:14:22 +0900951 }
952
Daniel Park2884b232021-03-04 18:58:47 +0900953 @Override
954 public void event(KubevirtRouterEvent event) {
955 switch (event.type()) {
956 case KUBEVIRT_ROUTER_CREATED:
957 eventExecutor.execute(() -> processRouterCreation(event.subject()));
958 break;
959 case KUBEVIRT_ROUTER_REMOVED:
960 eventExecutor.execute(() -> processRouterDeletion(event.subject()));
961 break;
962 case KUBEVIRT_ROUTER_UPDATED:
963 eventExecutor.execute(() -> processRouterUpdate(event.subject()));
964 break;
965 case KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED:
966 eventExecutor.execute(() -> processRouterInternalNetworksAttached(event.subject(),
967 event.internal()));
968 break;
969 case KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED:
970 eventExecutor.execute(() -> processRouterInternalNetworksDetached(event.subject(),
971 event.internal()));
972 break;
973 case KUBEVIRT_GATEWAY_NODE_ATTACHED:
974 eventExecutor.execute(() -> processRouterGatewayNodeAttached(event.subject(),
975 event.gateway()));
976 break;
977 case KUBEVIRT_GATEWAY_NODE_DETACHED:
978 eventExecutor.execute(() -> processRouterGatewayNodeDetached(event.subject(),
979 event.gateway()));
980 break;
981 case KUBEVIRT_GATEWAY_NODE_CHANGED:
982 eventExecutor.execute(() -> processRouterGatewayNodeChanged(event.subject(),
983 event.gateway()));
984 break;
Daniel Parka8968802021-02-25 09:14:22 +0900985
Daniel Park2884b232021-03-04 18:58:47 +0900986 default:
987 //do nothing
988 break;
989 }
990 }
991
992 private void processRouterCreation(KubevirtRouter router) {
993 // When a router is created, we performs the election process to associate the router
994 // to the specific gateway. After the election, KubevirtNetwork handler installs bunch of rules
995 // to elected gateway node so that VMs associated to the router can ping to their gateway IP.
996 // SNAT and floating ip rule setup is out of this handler's scope and would be done with the other handlers
997 if (!isRelevantHelper()) {
998 return;
999 }
1000 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1001 if (electedGw == null) {
1002 return;
1003 }
1004
1005 router.internal().forEach(networkName -> {
1006 KubevirtNetwork network = networkService.network(networkName);
1007
1008 if (network != null) {
1009 initGatewayNodeForInternalNetwork(network, router, electedGw, true);
1010 }
1011 });
1012 kubevirtRouterService.updateRouter(router.updatedElectedGateway(electedGw.hostname()));
1013 }
1014
1015 private void processRouterDeletion(KubevirtRouter router) {
1016 if (!isRelevantHelper()) {
1017 return;
1018 }
1019 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1020 if (electedGw == null) {
1021 return;
1022 }
1023
1024 router.internal().forEach(networkName -> {
1025 KubevirtNetwork network = networkService.network(networkName);
1026
1027 if (network != null) {
1028 initGatewayNodeForInternalNetwork(network, router, electedGw, false);
1029 }
1030 });
1031 }
1032
1033 private void processRouterUpdate(KubevirtRouter router) {
1034 if (!isRelevantHelper()) {
1035 return;
1036 }
1037 if (router.electedGateway() == null) {
1038 return;
1039 }
1040
1041 KubevirtNode electedGw = nodeService.node(router.electedGateway());
1042
1043 router.internal().forEach(networkName -> {
1044 KubevirtNetwork network = networkService.network(networkName);
1045
1046 if (network != null) {
1047 initGatewayNodeForInternalNetwork(network, router, electedGw, true);
1048 }
1049 });
1050 }
1051
1052 private void processRouterInternalNetworksAttached(KubevirtRouter router,
1053 Set<String> attachedInternalNetworks) {
1054 if (!isRelevantHelper()) {
1055 return;
1056 }
1057 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1058 if (electedGw == null) {
1059 return;
1060 }
1061
1062 attachedInternalNetworks.forEach(networkName -> {
1063 KubevirtNetwork network = networkService.network(networkName);
1064
1065 if (network != null) {
1066 initGatewayNodeForInternalNetwork(network, router, electedGw, true);
1067 }
1068 });
1069 }
1070
1071 private void processRouterInternalNetworksDetached(KubevirtRouter router,
1072 Set<String> detachedInternalNetworks) {
1073 if (!isRelevantHelper()) {
1074 return;
1075 }
1076 KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(nodeService, router);
1077 if (electedGw == null) {
1078 return;
1079 }
1080
1081 detachedInternalNetworks.forEach(networkName -> {
1082 KubevirtNetwork network = networkService.network(networkName);
1083
1084 if (network != null) {
1085 initGatewayNodeForInternalNetwork(network, router, electedGw, false);
1086 }
Daniel Park2884b232021-03-04 18:58:47 +09001087
Daniel Parkbabde9c2021-03-09 13:37:42 +09001088 removeDetachedInternalNetworkRules(network, router, electedGw);
1089 });
1090 }
1091
Jian Li8f944d42021-03-23 00:43:29 +09001092 private void removeDetachedInternalNetworkRules(KubevirtNetwork removedNetwork,
1093 KubevirtRouter router,
Daniel Parkbabde9c2021-03-09 13:37:42 +09001094 KubevirtNode electedGw) {
Daniel Parkf3136042021-03-10 07:49:11 +09001095 router.internal().stream().filter(networkId -> kubevirtNetworkService.network(networkId) != null)
1096 .forEach(networkId -> {
1097 kubevirtPortService.ports(networkId).forEach(kubevirtPort -> {
1098 setGatewayInterNetworkRoutingFromNetworkToPort(
1099 router, removedNetwork, kubevirtPort, electedGw, false);
1100 });
Daniel Parkbabde9c2021-03-09 13:37:42 +09001101 });
Daniel Park2884b232021-03-04 18:58:47 +09001102 }
1103
1104 private void processRouterGatewayNodeAttached(KubevirtRouter router,
1105 String associatedGateway) {
1106 if (!isRelevantHelper()) {
1107 return;
1108 }
1109
1110 KubevirtNode gatewayNode = nodeService.node(associatedGateway);
1111 if (gatewayNode == null) {
1112 return;
1113 }
1114
1115 router.internal().forEach(networkName -> {
1116 KubevirtNetwork network = networkService.network(networkName);
1117
1118 if (network != null) {
1119 initGatewayNodeForInternalNetwork(network, router, gatewayNode, true);
1120 }
1121 });
1122 }
1123
1124 private void processRouterGatewayNodeDetached(KubevirtRouter router,
1125 String disAssociatedGateway) {
1126 if (!isRelevantHelper()) {
1127 return;
1128 }
1129
1130 KubevirtNode gatewayNode = nodeService.node(disAssociatedGateway);
1131 if (gatewayNode == null) {
1132 return;
1133 }
1134
1135 router.internal().forEach(networkName -> {
1136 KubevirtNetwork network = networkService.network(networkName);
1137
1138 if (network != null) {
1139 initGatewayNodeForInternalNetwork(network, router, gatewayNode, false);
1140 }
1141 });
1142 }
1143
1144 private void processRouterGatewayNodeChanged(KubevirtRouter router,
1145 String disAssociatedGateway) {
1146 if (!isRelevantHelper()) {
1147 return;
1148 }
1149
1150 KubevirtNode oldGatewayNode = nodeService.node(disAssociatedGateway);
1151 if (oldGatewayNode == null) {
1152 return;
1153 }
1154
1155 router.internal().forEach(networkName -> {
1156 KubevirtNetwork network = networkService.network(networkName);
1157
1158 if (network != null) {
1159 initGatewayNodeForInternalNetwork(network, router, oldGatewayNode, false);
1160 }
1161 });
1162
1163 KubevirtNode newGatewayNode = nodeService.node(router.electedGateway());
1164 if (newGatewayNode == null) {
1165 return;
1166 }
1167
1168 router.internal().forEach(networkName -> {
1169 KubevirtNetwork network = networkService.network(networkName);
1170
1171 if (network != null) {
Daniel Parka5ba88d2021-05-28 15:46:46 +09001172 initGatewayNodeForInternalNetwork(network, router, newGatewayNode, true);
Daniel Park2884b232021-03-04 18:58:47 +09001173 }
1174 });
1175 }
Daniel Parka8968802021-02-25 09:14:22 +09001176 }
1177
Jian Li556709c2021-02-03 17:54:28 +09001178 private class InternalNetworkEventListener implements KubevirtNetworkListener {
1179
1180 private boolean isRelevantHelper() {
1181 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1182 }
1183
1184 @Override
1185 public void event(KubevirtNetworkEvent event) {
1186 switch (event.type()) {
1187 case KUBEVIRT_NETWORK_CREATED:
1188 eventExecutor.execute(() -> processNetworkCreation(event.subject()));
1189 break;
1190 case KUBEVIRT_NETWORK_REMOVED:
1191 eventExecutor.execute(() -> processNetworkRemoval(event.subject()));
1192 break;
1193 case KUBEVIRT_NETWORK_UPDATED:
1194 default:
1195 // do nothing
1196 break;
1197 }
1198 }
1199
1200 private void processNetworkCreation(KubevirtNetwork network) {
1201 if (!isRelevantHelper()) {
1202 return;
1203 }
1204
1205 switch (network.type()) {
1206 case VXLAN:
1207 case GRE:
1208 case GENEVE:
1209 initIntegrationTunnelBridge(network);
1210 break;
1211 case FLAT:
Jian Li2ce718e2021-02-17 20:42:15 +09001212 case VLAN:
Daniel Parka8968802021-02-25 09:14:22 +09001213 break;
Jian Li556709c2021-02-03 17:54:28 +09001214 default:
1215 // do nothing
1216 break;
1217 }
1218 }
1219
1220 private void processNetworkRemoval(KubevirtNetwork network) {
1221 if (!isRelevantHelper()) {
1222 return;
1223 }
1224
1225 switch (network.type()) {
1226 case VXLAN:
1227 case GRE:
1228 case GENEVE:
1229 purgeIntegrationTunnelBridge(network);
1230 break;
1231 case FLAT:
Jian Li2ce718e2021-02-17 20:42:15 +09001232 case VLAN:
Daniel Parka8968802021-02-25 09:14:22 +09001233 break;
Jian Li556709c2021-02-03 17:54:28 +09001234 default:
1235 // do nothing
1236 break;
1237 }
1238 }
1239
1240 private void initIntegrationTunnelBridge(KubevirtNetwork network) {
1241 if (network.segmentId() == null) {
1242 return;
1243 }
1244
Jian Li94b6d162021-04-15 17:09:11 +09001245 nodeService.completeNodes(WORKER).forEach(n -> {
Jian Li556709c2021-02-03 17:54:28 +09001246 createBridge(n, network);
Daniel Parkf3136042021-03-10 07:49:11 +09001247 createPatchTenantInterface(n, network);
1248 setDefaultRulesForTenantNetwork(n, network);
Jian Li556709c2021-02-03 17:54:28 +09001249 });
1250 }
1251
1252 private void purgeIntegrationTunnelBridge(KubevirtNetwork network) {
1253 if (network.segmentId() == null) {
1254 return;
1255 }
1256
Jian Li567b25c2021-05-27 15:17:59 +09001257 nodeService.completeNodes(WORKER).forEach(n -> {
Jian Liea1ead72021-05-28 11:00:07 +09001258 removeAllFlows(n, network);
Jian Li556709c2021-02-03 17:54:28 +09001259 removePatchInterface(n, network);
Jian Liea1ead72021-05-28 11:00:07 +09001260
Jian Li0c656f02021-06-07 13:32:39 +09001261 waitFor(5);
Jian Liea1ead72021-05-28 11:00:07 +09001262
Jian Li556709c2021-02-03 17:54:28 +09001263 removeBridge(n, network);
1264 });
1265 }
1266 }
1267
1268 private class InternalNodeEventListener implements KubevirtNodeListener {
1269
1270 private boolean isRelevantHelper() {
1271 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1272 }
1273
1274 @Override
1275 public void event(KubevirtNodeEvent event) {
1276 switch (event.type()) {
1277 case KUBEVIRT_NODE_COMPLETE:
1278 eventExecutor.execute(() -> processNodeCompletion(event.subject()));
1279 break;
Daniel Parka5ba88d2021-05-28 15:46:46 +09001280 case KUBEVIRT_NODE_INCOMPLETE:
Daniel Park2884b232021-03-04 18:58:47 +09001281 case KUBEVIRT_NODE_REMOVED:
1282 eventExecutor.execute(() -> processNodeDeletion(event.subject()));
1283 break;
Jian Li556709c2021-02-03 17:54:28 +09001284 case KUBEVIRT_NODE_UPDATED:
1285 default:
1286 // do nothing
1287 break;
1288 }
1289 }
1290
1291 private void processNodeCompletion(KubevirtNode node) {
1292 if (!isRelevantHelper()) {
1293 return;
1294 }
1295
Daniel Parka8968802021-02-25 09:14:22 +09001296 if (node.type().equals(WORKER)) {
1297 for (KubevirtNetwork network : networkService.networks()) {
1298 switch (network.type()) {
1299 case VXLAN:
1300 case GRE:
1301 case GENEVE:
1302 if (network.segmentId() == null) {
1303 continue;
1304 }
1305 createBridge(node, network);
Daniel Parkf3136042021-03-10 07:49:11 +09001306 createPatchTenantInterface(node, network);
1307 setDefaultRulesForTenantNetwork(node, network);
Jian Li8f944d42021-03-23 00:43:29 +09001308 setGatewayArpRulesForTenantNetwork(node, network);
1309 setGatewayIcmpRulesForTenantNetwork(node, network);
1310 setGatewayRuleToWorkerNodeWhenNodeCreated(node, network);
Daniel Parka8968802021-02-25 09:14:22 +09001311 break;
1312 case FLAT:
1313 case VLAN:
1314 default:
1315 // do nothing
1316 break;
1317 }
1318 }
1319 } else if (node.type().equals(GATEWAY)) {
Daniel Park2884b232021-03-04 18:58:47 +09001320 updateGatewayNodeForRouter();
Jian Li556709c2021-02-03 17:54:28 +09001321 }
1322 }
Daniel Park2884b232021-03-04 18:58:47 +09001323
1324 private void processNodeDeletion(KubevirtNode node) {
1325 if (!isRelevantHelper()) {
1326 return;
1327 }
Daniel Park2884b232021-03-04 18:58:47 +09001328 if (node.type().equals(GATEWAY)) {
Daniel Parka5ba88d2021-05-28 15:46:46 +09001329 kubevirtRouterService.routers()
1330 .stream()
1331 .filter(router -> router.electedGateway().equals(node.hostname()))
1332 .forEach(router -> {
1333 router.internal().forEach(networkName -> {
1334 KubevirtNetwork network = networkService.network(networkName);
1335
1336 if (network != null) {
1337 initGatewayNodeForInternalNetwork(network, router, node, false);
1338 }
1339 });
1340 });
Daniel Park2884b232021-03-04 18:58:47 +09001341 updateGatewayNodeForRouter();
Daniel Park2884b232021-03-04 18:58:47 +09001342 }
1343 }
1344
1345 private void updateGatewayNodeForRouter() {
1346 kubevirtRouterService.routers().forEach(router -> {
1347 KubevirtNode newGwNode = gatewayNodeForSpecifiedRouter(nodeService, router);
1348
1349 if (newGwNode == null) {
1350 return;
1351 }
1352 kubevirtRouterService.updateRouter(router.updatedElectedGateway(newGwNode.hostname()));
1353 });
1354 }
Jian Li556709c2021-02-03 17:54:28 +09001355 }
Daniel Parkbabde9c2021-03-09 13:37:42 +09001356
1357 private class InternalKubevirtPortListener implements KubevirtPortListener {
1358
1359 private boolean isRelevantHelper() {
1360 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1361 }
1362
1363 @Override
1364 public void event(KubevirtPortEvent event) {
1365 switch (event.type()) {
1366 case KUBEVIRT_PORT_CREATED:
1367 eventExecutor.execute(() -> processPortCreation(event.subject()));
1368 break;
1369 case KUBEVIRT_PORT_UPDATED:
1370 eventExecutor.execute(() -> processPortUpdate(event.subject()));
1371 break;
1372 case KUBEVIRT_PORT_REMOVED:
1373 eventExecutor.execute(() -> processPortDeletion(event.subject()));
1374 break;
1375 default:
1376 //do nothing
1377 break;
1378 }
1379 }
1380
1381 private void processPortCreation(KubevirtPort kubevirtPort) {
1382 if (!isRelevantHelper()) {
1383 return;
1384 }
1385
1386 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
1387 if (router == null) {
1388 return;
1389 }
1390
1391 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
1392
1393 if (gwNode != null) {
1394
1395 router.internal().forEach(srcNetwork -> {
1396 if (srcNetwork.equals(kubevirtPort.networkId())
1397 || kubevirtNetworkService.network(srcNetwork) == null) {
1398 return;
1399 }
Jian Li8f944d42021-03-23 00:43:29 +09001400 setGatewayInterNetworkRoutingFromNetworkToPort(router,
1401 kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +09001402 kubevirtPort, gwNode, true);
1403 });
1404 }
1405 }
1406
1407 private void processPortUpdate(KubevirtPort kubevirtPort) {
1408 if (!isRelevantHelper()) {
1409 return;
1410 }
1411
1412 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
1413 if (router == null) {
1414 return;
1415 }
1416
1417 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
1418
1419 if (gwNode != null) {
1420
1421 router.internal().forEach(srcNetwork -> {
1422 if (srcNetwork.equals(kubevirtPort.networkId())
1423 || kubevirtNetworkService.network(srcNetwork) == null) {
1424 return;
1425 }
Jian Li8f944d42021-03-23 00:43:29 +09001426 setGatewayInterNetworkRoutingFromNetworkToPort(router,
1427 kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +09001428 kubevirtPort, gwNode, true);
1429 });
1430 }
1431 }
1432
1433 private void processPortDeletion(KubevirtPort kubevirtPort) {
1434 if (!isRelevantHelper()) {
1435 return;
1436 }
1437
1438 KubevirtRouter router = getRouterForKubevirtPort(kubevirtRouterService, kubevirtPort);
1439 if (router == null) {
1440 return;
1441 }
1442
1443 KubevirtNode gwNode = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
1444
1445 if (gwNode != null) {
1446
1447 router.internal().forEach(srcNetwork -> {
1448 if (srcNetwork.equals(kubevirtPort.networkId())
1449 || kubevirtNetworkService.network(srcNetwork) == null) {
1450 return;
1451 }
Jian Li8f944d42021-03-23 00:43:29 +09001452 setGatewayInterNetworkRoutingFromNetworkToPort(router,
1453 kubevirtNetworkService.network(srcNetwork),
Daniel Parkbabde9c2021-03-09 13:37:42 +09001454 kubevirtPort, gwNode, false);
1455 });
1456 }
Daniel Parkbabde9c2021-03-09 13:37:42 +09001457 }
1458 }
Jian Li556709c2021-02-03 17:54:28 +09001459}