blob: 71dbe5a99a900a7ce747f79a0bca394936c35c2b [file] [log] [blame]
Hyunsun Moon44aac662017-02-18 02:07:01 +09001/*
Jian Li26949762018-03-30 15:46:37 +09002 * Copyright 2016-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 */
Hyunsun Moon44aac662017-02-18 02:07:01 +090016
17package org.onosproject.openstacknetworking.impl;
18
19import com.google.common.base.Strings;
Hyunsun Moon44aac662017-02-18 02:07:01 +090020import org.onlab.packet.Ethernet;
daniel parka792cf72017-04-14 16:25:35 +090021import org.onlab.packet.VlanId;
Jian Li5c09e212018-10-24 18:23:58 +090022import org.onosproject.cfg.ComponentConfigService;
23import org.onosproject.cfg.ConfigProperty;
Jian Li91be8cd2018-07-22 00:44:46 +090024import org.onosproject.cluster.ClusterService;
25import org.onosproject.cluster.LeadershipService;
26import org.onosproject.cluster.NodeId;
Hyunsun Moon44aac662017-02-18 02:07:01 +090027import org.onosproject.core.ApplicationId;
28import org.onosproject.core.CoreService;
29import org.onosproject.mastership.MastershipService;
daniel park796c2eb2018-03-22 17:01:51 +090030import org.onosproject.net.PortNumber;
Hyunsun Moon44aac662017-02-18 02:07:01 +090031import org.onosproject.net.device.DeviceService;
sangho1aaa7882017-05-31 13:22:47 +090032import org.onosproject.net.driver.DriverService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090033import org.onosproject.net.flow.DefaultTrafficSelector;
34import org.onosproject.net.flow.DefaultTrafficTreatment;
35import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
Hyunsun Moon44aac662017-02-18 02:07:01 +090037import org.onosproject.openstacknetworking.api.InstancePort;
38import org.onosproject.openstacknetworking.api.InstancePortEvent;
39import org.onosproject.openstacknetworking.api.InstancePortListener;
40import org.onosproject.openstacknetworking.api.InstancePortService;
sanghodc375372017-06-08 10:41:30 +090041import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
SONA Project6bc5c4a2018-12-14 23:49:52 +090042import org.onosproject.openstacknetworking.api.OpenstackNetwork.Type;
Jian Li91be8cd2018-07-22 00:44:46 +090043import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
44import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
Hyunsun Moon44aac662017-02-18 02:07:01 +090045import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
Hyunsun Moon0d457362017-06-27 17:19:41 +090046import org.onosproject.openstacknode.api.OpenstackNode;
47import org.onosproject.openstacknode.api.OpenstackNodeService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090048import org.openstack4j.model.network.Network;
Frank Wangf9571662017-06-06 18:01:29 +080049import org.openstack4j.model.network.Port;
Jian Li34220ea2018-11-14 01:30:24 +090050import org.osgi.service.component.annotations.Activate;
51import org.osgi.service.component.annotations.Component;
52import org.osgi.service.component.annotations.Deactivate;
53import org.osgi.service.component.annotations.Reference;
54import org.osgi.service.component.annotations.ReferenceCardinality;
Hyunsun Moon44aac662017-02-18 02:07:01 +090055import org.slf4j.Logger;
56
Jian Li91be8cd2018-07-22 00:44:46 +090057import java.util.Objects;
Jian Li5c09e212018-10-24 18:23:58 +090058import java.util.Set;
Hyunsun Moon44aac662017-02-18 02:07:01 +090059import java.util.concurrent.ExecutorService;
60
61import static java.util.concurrent.Executors.newSingleThreadExecutor;
62import static org.onlab.util.Tools.groupedThreads;
Jian Li1e9cb732018-11-25 23:17:21 +090063import static org.onosproject.openstacknetworking.api.Constants.ACL_EGRESS_TABLE;
Jian Li5c09e212018-10-24 18:23:58 +090064import static org.onosproject.openstacknetworking.api.Constants.ARP_BROADCAST_MODE;
65import static org.onosproject.openstacknetworking.api.Constants.ARP_TABLE;
66import static org.onosproject.openstacknetworking.api.Constants.DHCP_TABLE;
Jian Li70a2c3f2018-04-13 17:26:31 +090067import static org.onosproject.openstacknetworking.api.Constants.FLAT_TABLE;
sanghodc375372017-06-08 10:41:30 +090068import static org.onosproject.openstacknetworking.api.Constants.FORWARDING_TABLE;
69import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
Frank Wangf9571662017-06-06 18:01:29 +080070import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ADMIN_RULE;
Daniel Parkd1b14d32018-06-12 16:10:28 +090071import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLAT_DOWNSTREAM_RULE;
Daniel Parkd1b14d32018-06-12 16:10:28 +090072import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLAT_JUMP_UPSTREAM_RULE;
73import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLAT_UPSTREAM_RULE;
sanghodc375372017-06-08 10:41:30 +090074import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
75import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_TUNNEL_TAG_RULE;
Jian Li960ae512018-07-03 22:50:56 +090076import static org.onosproject.openstacknetworking.api.Constants.STAT_FLAT_OUTBOUND_TABLE;
Jian Li70a2c3f2018-04-13 17:26:31 +090077import static org.onosproject.openstacknetworking.api.Constants.VTAG_TABLE;
Jian Li34220ea2018-11-14 01:30:24 +090078import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_STARTED;
Jian Li5c09e212018-10-24 18:23:58 +090079import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
Jian Liec5c32b2018-07-13 14:28:58 +090080import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
Jian Li2d68c192018-12-13 15:52:59 +090081import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.tunnelPortNumByNetId;
Jian Li26949762018-03-30 15:46:37 +090082import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
Hyunsun Moon0d457362017-06-27 17:19:41 +090083import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
Hyunsun Moon44aac662017-02-18 02:07:01 +090084import static org.slf4j.LoggerFactory.getLogger;
85
86
87/**
88 * Populates switching flow rules on OVS for the basic connectivity among the
89 * virtual instances in the same network.
90 */
91@Component(immediate = true)
Jian Li4d138702018-11-27 17:25:28 +090092public class OpenstackSwitchingHandler {
Hyunsun Moon44aac662017-02-18 02:07:01 +090093
94 private final Logger log = getLogger(getClass());
95
Jian Li5c09e212018-10-24 18:23:58 +090096 private static final String ARP_MODE = "arpMode";
Jian Li4d138702018-11-27 17:25:28 +090097 private static final String ERR_SET_FLOWS_VNI = "Failed to set flows for " +
98 "%s: Failed to get VNI for %s";
99 private static final String STR_NONE = "<none>";
Hyunsun Moon44aac662017-02-18 02:07:01 +0900100
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700101 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900102 protected CoreService coreService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900103
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700104 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900105 protected MastershipService mastershipService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900106
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700107 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900108 protected DeviceService deviceService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900109
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700110 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li91be8cd2018-07-22 00:44:46 +0900111 protected DriverService driverService;
112
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700113 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li91be8cd2018-07-22 00:44:46 +0900114 protected ClusterService clusterService;
115
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700116 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li5c09e212018-10-24 18:23:58 +0900117 protected ComponentConfigService configService;
118
Ray Milkey956bb162018-10-26 10:53:44 -0700119 @Reference(cardinality = ReferenceCardinality.MANDATORY)
120
Jian Li91be8cd2018-07-22 00:44:46 +0900121 protected LeadershipService leadershipService;
122
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700123 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900124 protected OpenstackFlowRuleService osFlowRuleService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900125
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700126 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900127 protected InstancePortService instancePortService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900128
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700129 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900130 protected OpenstackNetworkService osNetworkService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900131
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700132 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900133 protected OpenstackNodeService osNodeService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900134
135 private final ExecutorService eventExecutor = newSingleThreadExecutor(
136 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
137 private final InstancePortListener instancePortListener = new InternalInstancePortListener();
Jian Li91be8cd2018-07-22 00:44:46 +0900138 private final InternalOpenstackNetworkListener osNetworkListener =
139 new InternalOpenstackNetworkListener();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900140 private ApplicationId appId;
Jian Li91be8cd2018-07-22 00:44:46 +0900141 private NodeId localNodeId;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900142
143 @Activate
Jian Li4d138702018-11-27 17:25:28 +0900144 protected void activate() {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900145 appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
Jian Li91be8cd2018-07-22 00:44:46 +0900146 localNodeId = clusterService.getLocalNode().id();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900147 instancePortService.addListener(instancePortListener);
Jian Li91be8cd2018-07-22 00:44:46 +0900148 osNetworkService.addListener(osNetworkListener);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900149
150 log.info("Started");
151 }
152
153 @Deactivate
Jian Li4d138702018-11-27 17:25:28 +0900154 protected void deactivate() {
Jian Li91be8cd2018-07-22 00:44:46 +0900155 osNetworkService.removeListener(osNetworkListener);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900156 instancePortService.removeListener(instancePortListener);
157 eventExecutor.shutdown();
158
159 log.info("Stopped");
160 }
161
Jian Li70a2c3f2018-04-13 17:26:31 +0900162 private void setFlatJumpRules(InstancePort port, boolean install) {
163 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
164 selector.matchInPort(port.portNumber());
165
166 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Jian Li960ae512018-07-03 22:50:56 +0900167 treatment.transition(STAT_FLAT_OUTBOUND_TABLE);
Jian Li70a2c3f2018-04-13 17:26:31 +0900168
169 osFlowRuleService.setRule(
170 appId,
171 port.deviceId(),
172 selector.build(),
173 treatment.build(),
Daniel Parkd1b14d32018-06-12 16:10:28 +0900174 PRIORITY_FLAT_JUMP_UPSTREAM_RULE,
Jian Li5c09e212018-10-24 18:23:58 +0900175 DHCP_TABLE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900176 install);
177
178 Network network = osNetworkService.network(port.networkId());
179
180 if (network == null) {
181 log.warn("The network does not exist");
182 return;
183 }
Jian Li70a2c3f2018-04-13 17:26:31 +0900184 PortNumber portNumber = osNodeService.node(port.deviceId())
185 .phyIntfPortNum(network.getProviderPhyNet());
186
187 if (portNumber == null) {
188 log.warn("The port number does not exist");
189 return;
190 }
Jian Li70a2c3f2018-04-13 17:26:31 +0900191 }
192
Jian Li9a921b42018-06-18 02:44:50 +0900193 private void setDownstreamRulesForFlat(InstancePort instPort, boolean install) {
daniel park796c2eb2018-03-22 17:01:51 +0900194 TrafficSelector selector = DefaultTrafficSelector.builder()
195 .matchEthType(Ethernet.TYPE_IPV4)
196 .matchIPDst(instPort.ipAddress().toIpPrefix())
197 .build();
198 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
199 .setOutput(instPort.portNumber())
200 .build();
201
202 osFlowRuleService.setRule(
203 appId,
204 instPort.deviceId(),
205 selector,
206 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900207 PRIORITY_FLAT_DOWNSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900208 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900209 install);
210
211 selector = DefaultTrafficSelector.builder()
212 .matchEthType(Ethernet.TYPE_ARP)
213 .matchArpTpa(instPort.ipAddress().getIp4Address())
214 .build();
215
216 osFlowRuleService.setRule(
217 appId,
218 instPort.deviceId(),
219 selector,
220 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900221 PRIORITY_FLAT_DOWNSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900222 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900223 install);
224 }
225
Jian Li9a921b42018-06-18 02:44:50 +0900226 private void setUpstreamRulesForFlat(InstancePort instPort, boolean install) {
daniel park796c2eb2018-03-22 17:01:51 +0900227 TrafficSelector selector = DefaultTrafficSelector.builder()
228 .matchInPort(instPort.portNumber())
229 .build();
230
231 Network network = osNetworkService.network(instPort.networkId());
232
233 if (network == null) {
234 log.warn("The network does not exist");
235 return;
236 }
237
238 PortNumber portNumber = osNodeService.node(instPort.deviceId())
239 .phyIntfPortNum(network.getProviderPhyNet());
240
241 if (portNumber == null) {
242 log.warn("The port number does not exist");
243 return;
244 }
245
246 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
247 .setOutput(portNumber)
248 .build();
249
250 osFlowRuleService.setRule(
251 appId,
252 instPort.deviceId(),
253 selector,
254 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900255 PRIORITY_FLAT_UPSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900256 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900257 install);
258 }
259
Jian Liea1b9662018-03-02 18:07:32 +0900260 /**
261 * Configures the flow rules which are used for L2 packet switching.
262 * Note that these rules will be inserted in switching table (table 5).
263 *
264 * @param instPort instance port object
265 * @param install install flag, add the rule if true, remove it otherwise
266 */
Jian Li2d68c192018-12-13 15:52:59 +0900267 private void setForwardingRulesForTunnel(InstancePort instPort, boolean install) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900268 // switching rules for the instPorts in the same node
269 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900270 // TODO: need to handle IPv6 in near future
Hyunsun Moon44aac662017-02-18 02:07:01 +0900271 .matchEthType(Ethernet.TYPE_IPV4)
272 .matchIPDst(instPort.ipAddress().toIpPrefix())
273 .matchTunnelId(getVni(instPort))
274 .build();
275
276 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900277 // TODO: this might not be necessary for the VMs located in the same subnet
Hyunsun Moon44aac662017-02-18 02:07:01 +0900278 .setEthDst(instPort.macAddress())
279 .setOutput(instPort.portNumber())
280 .build();
281
sanghodc375372017-06-08 10:41:30 +0900282 osFlowRuleService.setRule(
Hyunsun Moon44aac662017-02-18 02:07:01 +0900283 appId,
284 instPort.deviceId(),
285 selector,
286 treatment,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900287 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900288 FORWARDING_TABLE,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900289 install);
290
291 // switching rules for the instPorts in the remote node
Hyunsun Moon0d457362017-06-27 17:19:41 +0900292 OpenstackNode localNode = osNodeService.node(instPort.deviceId());
293 if (localNode == null) {
294 final String error = String.format("Cannot find openstack node for %s",
295 instPort.deviceId());
296 throw new IllegalStateException(error);
297 }
298 osNodeService.completeNodes(COMPUTE).stream()
299 .filter(remoteNode -> !remoteNode.intgBridge().equals(localNode.intgBridge()))
300 .forEach(remoteNode -> {
Jian Li2d68c192018-12-13 15:52:59 +0900301 PortNumber portNum = tunnelPortNumByNetId(instPort.networkId(),
302 osNetworkService, remoteNode);
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900303 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
304 .extension(buildExtension(
305 deviceService,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900306 remoteNode.intgBridge(),
307 localNode.dataIp().getIp4Address()),
308 remoteNode.intgBridge())
Jian Li2d68c192018-12-13 15:52:59 +0900309 .setOutput(portNum)
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900310 .build();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900311
sanghodc375372017-06-08 10:41:30 +0900312 osFlowRuleService.setRule(
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900313 appId,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900314 remoteNode.intgBridge(),
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900315 selector,
316 treatmentToRemote,
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900317 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900318 FORWARDING_TABLE,
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900319 install);
320 });
Hyunsun Moon44aac662017-02-18 02:07:01 +0900321 }
322
Jian Liea1b9662018-03-02 18:07:32 +0900323 /**
324 * Configures the flow rules which are used for L2 VLAN packet switching.
325 * Note that these rules will be inserted in switching table (table 5).
326 *
327 * @param instPort instance port object
328 * @param install install flag, add the rule if true, remove it otherwise
329 */
daniel parka792cf72017-04-14 16:25:35 +0900330 private void setForwardingRulesForVlan(InstancePort instPort, boolean install) {
331 // switching rules for the instPorts in the same node
332 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900333 // TODO: need to handle IPv6 in near future
daniel parka792cf72017-04-14 16:25:35 +0900334 .matchEthType(Ethernet.TYPE_IPV4)
335 .matchIPDst(instPort.ipAddress().toIpPrefix())
336 .matchVlanId(getVlanId(instPort))
337 .build();
338
339 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
340 .popVlan()
Jian Liea1b9662018-03-02 18:07:32 +0900341 // TODO: this might not be necessary for the VMs located in the same subnet
daniel parka792cf72017-04-14 16:25:35 +0900342 .setEthDst(instPort.macAddress())
343 .setOutput(instPort.portNumber())
344 .build();
345
sanghodc375372017-06-08 10:41:30 +0900346 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900347 appId,
348 instPort.deviceId(),
349 selector,
350 treatment,
daniel parka792cf72017-04-14 16:25:35 +0900351 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900352 FORWARDING_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900353 install);
354
355 // switching rules for the instPorts in the remote node
Hyunsun Moon0d457362017-06-27 17:19:41 +0900356 osNodeService.completeNodes(COMPUTE).stream()
357 .filter(remoteNode -> !remoteNode.intgBridge().equals(instPort.deviceId()) &&
358 remoteNode.vlanIntf() != null)
359 .forEach(remoteNode -> {
daniel parka792cf72017-04-14 16:25:35 +0900360 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
Daniel Parkc64b4c62018-05-09 18:13:39 +0900361 .setEthDst(instPort.macAddress())
362 .setOutput(remoteNode.vlanPortNum())
363 .build();
daniel parka792cf72017-04-14 16:25:35 +0900364
sanghodc375372017-06-08 10:41:30 +0900365 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900366 appId,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900367 remoteNode.intgBridge(),
daniel parka792cf72017-04-14 16:25:35 +0900368 selector,
369 treatmentToRemote,
daniel parka792cf72017-04-14 16:25:35 +0900370 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900371 FORWARDING_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900372 install);
373 });
daniel parka792cf72017-04-14 16:25:35 +0900374 }
375
Jian Li5c09e212018-10-24 18:23:58 +0900376 private void setTunnelTagArpFlowRules(InstancePort instPort, boolean install) {
377 setTunnelTagFlowRules(instPort, Ethernet.TYPE_ARP, install);
378 }
379
380 private void setTunnelTagIpFlowRules(InstancePort instPort, boolean install) {
381 setTunnelTagFlowRules(instPort, Ethernet.TYPE_IPV4, install);
382 }
383
Jian Liea1b9662018-03-02 18:07:32 +0900384 /**
Jian Li2d68c192018-12-13 15:52:59 +0900385 * Configures the flow rule which is for using VXLAN/GRE to tag the packet
Jian Liea1b9662018-03-02 18:07:32 +0900386 * based on the in_port number of a virtual instance.
Jian Li5c09e212018-10-24 18:23:58 +0900387 * Note that this rule will be inserted in vTag table.
Jian Liea1b9662018-03-02 18:07:32 +0900388 *
389 * @param instPort instance port object
390 * @param install install flag, add the rule if true, remove it otherwise
391 */
Jian Li5c09e212018-10-24 18:23:58 +0900392 private void setTunnelTagFlowRules(InstancePort instPort,
393 short ethType,
394 boolean install) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900395 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li5c09e212018-10-24 18:23:58 +0900396 .matchEthType(ethType)
Hyunsun Moon44aac662017-02-18 02:07:01 +0900397 .matchInPort(instPort.portNumber())
398 .build();
399
Jian Li28ec77f2018-10-31 07:07:25 +0900400 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
401 .setTunnelId(getVni(instPort));
sangho1aaa7882017-05-31 13:22:47 +0900402
sanghoe6457a32017-08-24 14:31:19 +0900403
Jian Li28ec77f2018-10-31 07:07:25 +0900404 if (ethType == Ethernet.TYPE_ARP) {
405 tBuilder.transition(ARP_TABLE);
406 } else if (ethType == Ethernet.TYPE_IPV4) {
Jian Li1e9cb732018-11-25 23:17:21 +0900407 tBuilder.transition(ACL_EGRESS_TABLE);
sanghoe6457a32017-08-24 14:31:19 +0900408 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900409
sanghodc375372017-06-08 10:41:30 +0900410 osFlowRuleService.setRule(
Hyunsun Moon44aac662017-02-18 02:07:01 +0900411 appId,
412 instPort.deviceId(),
413 selector,
Jian Li28ec77f2018-10-31 07:07:25 +0900414 tBuilder.build(),
Hyunsun Moon44aac662017-02-18 02:07:01 +0900415 PRIORITY_TUNNEL_TAG_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900416 VTAG_TABLE,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900417 install);
418 }
419
Jian Li5c09e212018-10-24 18:23:58 +0900420 private void setVlanTagIpFlowRules(InstancePort instPort, boolean install) {
421 setVlanTagFlowRules(instPort, Ethernet.TYPE_IPV4, install);
422 }
423
424 private void setVlanTagArpFlowRules(InstancePort instPort, boolean install) {
425 setVlanTagFlowRules(instPort, Ethernet.TYPE_ARP, install);
426 }
427
Jian Liea1b9662018-03-02 18:07:32 +0900428 /**
429 * Configures the flow rule which is for using VLAN to tag the packet
430 * based on the in_port number of a virtual instance.
Jian Li5c09e212018-10-24 18:23:58 +0900431 * Note that this rule will be inserted in vTag table.
Jian Liea1b9662018-03-02 18:07:32 +0900432 *
433 * @param instPort instance port object
434 * @param install install flag, add the rule if true, remove it otherwise
435 */
Jian Li5c09e212018-10-24 18:23:58 +0900436 private void setVlanTagFlowRules(InstancePort instPort,
437 short ethType,
438 boolean install) {
daniel parka792cf72017-04-14 16:25:35 +0900439 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li5c09e212018-10-24 18:23:58 +0900440 .matchEthType(ethType)
daniel parka792cf72017-04-14 16:25:35 +0900441 .matchInPort(instPort.portNumber())
442 .build();
443
Daniel Park8a9220f2018-11-19 18:58:35 +0900444 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
daniel parka792cf72017-04-14 16:25:35 +0900445 .pushVlan()
Daniel Park8a9220f2018-11-19 18:58:35 +0900446 .setVlanId(getVlanId(instPort));
447
448 if (ethType == Ethernet.TYPE_ARP) {
449 tBuilder.transition(ARP_TABLE);
450 } else if (ethType == Ethernet.TYPE_IPV4) {
Jian Li1e9cb732018-11-25 23:17:21 +0900451 tBuilder.transition(ACL_EGRESS_TABLE);
Daniel Park8a9220f2018-11-19 18:58:35 +0900452 }
daniel parka792cf72017-04-14 16:25:35 +0900453
sanghodc375372017-06-08 10:41:30 +0900454 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900455 appId,
456 instPort.deviceId(),
457 selector,
Daniel Park8a9220f2018-11-19 18:58:35 +0900458 tBuilder.build(),
daniel parka792cf72017-04-14 16:25:35 +0900459 PRIORITY_TUNNEL_TAG_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900460 VTAG_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900461 install);
daniel parka792cf72017-04-14 16:25:35 +0900462 }
463
Jian Li91be8cd2018-07-22 00:44:46 +0900464 private void setNetworkBlockRules(Network network, boolean install) {
Frank Wangf9571662017-06-06 18:01:29 +0800465
SONA Project6bc5c4a2018-12-14 23:49:52 +0900466 Type type = osNetworkService.networkType(network.getId());
Jian Li91be8cd2018-07-22 00:44:46 +0900467
468 // TODO: we block a network traffic by referring to segment ID for now
469 // we might need to find a better way to block the traffic of a network
Jian Li2d68c192018-12-13 15:52:59 +0900470 // in case the segment ID is overlapped in different types network (VXLAN, GRE, VLAN)
Jian Li91be8cd2018-07-22 00:44:46 +0900471 switch (type) {
472 case VXLAN:
Jian Li2d68c192018-12-13 15:52:59 +0900473 case GRE:
Jian Li621f73c2018-12-15 01:49:22 +0900474 case GENEVE:
Jian Li2d68c192018-12-13 15:52:59 +0900475 setNetworkBlockRulesForTunnel(network.getProviderSegID(), install);
Jian Li91be8cd2018-07-22 00:44:46 +0900476 break;
477 case VLAN:
478 setNetworkBlockRulesForVlan(network.getProviderSegID(), install);
479 break;
480 case FLAT:
481 // TODO: need to find a way to block flat typed network
482 break;
483 default:
484 break;
Frank Wangf9571662017-06-06 18:01:29 +0800485 }
Jian Li91be8cd2018-07-22 00:44:46 +0900486 }
487
Jian Li2d68c192018-12-13 15:52:59 +0900488 private void setNetworkBlockRulesForTunnel(String segmentId, boolean install) {
Jian Li91be8cd2018-07-22 00:44:46 +0900489 TrafficSelector selector = DefaultTrafficSelector.builder()
490 .matchTunnelId(Long.valueOf(segmentId))
491 .build();
Frank Wangf9571662017-06-06 18:01:29 +0800492
493 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
494 .drop()
495 .build();
496
Jian Li91be8cd2018-07-22 00:44:46 +0900497 osNodeService.completeNodes(COMPUTE)
Jian Liea1b9662018-03-02 18:07:32 +0900498 .forEach(osNode ->
Frank Wangf9571662017-06-06 18:01:29 +0800499 osFlowRuleService.setRule(
Jian Li91be8cd2018-07-22 00:44:46 +0900500 appId,
501 osNode.intgBridge(),
502 selector,
503 treatment,
504 PRIORITY_ADMIN_RULE,
Jian Li1e9cb732018-11-25 23:17:21 +0900505 ACL_EGRESS_TABLE,
Jian Li91be8cd2018-07-22 00:44:46 +0900506 install)
Jian Liea1b9662018-03-02 18:07:32 +0900507 );
Frank Wangf9571662017-06-06 18:01:29 +0800508 }
509
Jian Li91be8cd2018-07-22 00:44:46 +0900510 private void setNetworkBlockRulesForVlan(String segmentId, boolean install) {
Frank Wangf9571662017-06-06 18:01:29 +0800511 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li91be8cd2018-07-22 00:44:46 +0900512 .matchTunnelId(Long.valueOf(segmentId))
513 .build();
514
515 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
516 .drop()
517 .build();
518
519 osNodeService.completeNodes(COMPUTE)
520 .forEach(osNode ->
521 osFlowRuleService.setRule(
522 appId,
523 osNode.intgBridge(),
524 selector,
525 treatment,
526 PRIORITY_ADMIN_RULE,
Jian Li1e9cb732018-11-25 23:17:21 +0900527 ACL_EGRESS_TABLE,
Jian Li91be8cd2018-07-22 00:44:46 +0900528 install)
529 );
530 }
531
532 private void setPortBlockRules(InstancePort instPort, boolean install) {
533 TrafficSelector selector = DefaultTrafficSelector.builder()
534 .matchInPort(instPort.portNumber())
Frank Wangf9571662017-06-06 18:01:29 +0800535 .build();
536
537 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
538 .drop()
539 .build();
540
541 osFlowRuleService.setRule(
542 appId,
Jian Li91be8cd2018-07-22 00:44:46 +0900543 instPort.deviceId(),
Frank Wangf9571662017-06-06 18:01:29 +0800544 selector,
545 treatment,
546 PRIORITY_ADMIN_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900547 VTAG_TABLE,
Frank Wangf9571662017-06-06 18:01:29 +0800548 install);
549 }
550
Jian Liea1b9662018-03-02 18:07:32 +0900551 /**
552 * Obtains the VLAN ID from the given instance port.
553 *
554 * @param instPort instance port object
555 * @return VLAN ID
556 */
daniel parka792cf72017-04-14 16:25:35 +0900557 private VlanId getVlanId(InstancePort instPort) {
558 Network osNet = osNetworkService.network(instPort.networkId());
559
560 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900561 final String error =
562 String.format(ERR_SET_FLOWS_VNI,
Jian Li4d138702018-11-27 17:25:28 +0900563 instPort, osNet == null ? STR_NONE : osNet.getName());
daniel parka792cf72017-04-14 16:25:35 +0900564 throw new IllegalStateException(error);
565 }
566
567 return VlanId.vlanId(osNet.getProviderSegID());
568 }
569
Jian Liea1b9662018-03-02 18:07:32 +0900570 /**
571 * Obtains the VNI from the given instance port.
572 *
573 * @param instPort instance port object
Jian Li2d68c192018-12-13 15:52:59 +0900574 * @return Virtual Network Identifier (VNI)
Jian Liea1b9662018-03-02 18:07:32 +0900575 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900576 private Long getVni(InstancePort instPort) {
577 Network osNet = osNetworkService.network(instPort.networkId());
578 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900579 final String error =
580 String.format(ERR_SET_FLOWS_VNI,
Jian Li4d138702018-11-27 17:25:28 +0900581 instPort, osNet == null ? STR_NONE : osNet.getName());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900582 throw new IllegalStateException(error);
583 }
584 return Long.valueOf(osNet.getProviderSegID());
585 }
586
Jian Li5c09e212018-10-24 18:23:58 +0900587 private String getArpMode() {
Jian Li34220ea2018-11-14 01:30:24 +0900588 Set<ConfigProperty> properties =
589 configService.getProperties(OpenstackSwitchingArpHandler.class.getName());
Jian Li5c09e212018-10-24 18:23:58 +0900590 return getPropertyValue(properties, ARP_MODE);
591 }
592
Jian Liea1b9662018-03-02 18:07:32 +0900593 /**
594 * An internal instance port listener which listens the port events generated
595 * from VM. The corresponding L2 forwarding rules will be generated and
596 * inserted to integration bridge only if a new VM port is detected. If the
597 * existing detected VM port is removed due to VM purge, we will remove the
598 * corresponding L2 forwarding to as well for the sake of resource saving.
599 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900600 private class InternalInstancePortListener implements InstancePortListener {
601
Jian Li34220ea2018-11-14 01:30:24 +0900602 private boolean isRelevantHelper(InstancePortEvent event) {
603 return mastershipService.isLocalMaster(event.subject().deviceId());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900604 }
605
606 @Override
607 public void event(InstancePortEvent event) {
608 InstancePort instPort = event.subject();
Jian Li9a921b42018-06-18 02:44:50 +0900609
Hyunsun Moon44aac662017-02-18 02:07:01 +0900610 switch (event.type()) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900611 case OPENSTACK_INSTANCE_PORT_DETECTED:
Jian Liec5c32b2018-07-13 14:28:58 +0900612 case OPENSTACK_INSTANCE_PORT_UPDATED:
Jian Li34220ea2018-11-14 01:30:24 +0900613 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
Jian Li46b74002018-07-15 18:39:08 +0900614 case OPENSTACK_INSTANCE_RESTARTED:
Jian Li4d138702018-11-27 17:25:28 +0900615 eventExecutor.execute(() ->
616 processInstanceDetection(event, instPort));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900617 break;
Jian Li46b74002018-07-15 18:39:08 +0900618 case OPENSTACK_INSTANCE_TERMINATED:
Jian Li4d138702018-11-27 17:25:28 +0900619 eventExecutor.execute(() ->
620 processInstanceTermination(event, instPort));
Jian Li46b74002018-07-15 18:39:08 +0900621 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900622 case OPENSTACK_INSTANCE_PORT_VANISHED:
Jian Li4d138702018-11-27 17:25:28 +0900623 eventExecutor.execute(() ->
624 processInstanceRemoval(event, instPort));
Jian Liec5c32b2018-07-13 14:28:58 +0900625 break;
626 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
Jian Li4d138702018-11-27 17:25:28 +0900627 eventExecutor.execute(() ->
628 processInstanceMigrationEnd(event, instPort));
Jian Li24ec59f2018-05-23 19:01:25 +0900629 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900630 default:
631 break;
632 }
633 }
634
Jian Li4d138702018-11-27 17:25:28 +0900635 private void processInstanceDetection(InstancePortEvent event,
636 InstancePort instPort) {
637 if (!isRelevantHelper(event)) {
638 return;
639 }
640
641 if (event.type() == OPENSTACK_INSTANCE_MIGRATION_STARTED) {
642 log.info("SwitchingHandler: Migration started at MAC:{} IP:{}",
643 instPort.macAddress(),
644 instPort.ipAddress());
645 } else {
646 log.info("SwitchingHandler: Instance port detected MAC:{} IP:{}",
647 instPort.macAddress(),
648 instPort.ipAddress());
649 }
650
651 instPortDetected(instPort);
652
653 Port osPort = osNetworkService.port(instPort.portId());
654
655 if (osPort != null) {
656 setPortBlockRules(instPort, !osPort.isAdminStateUp());
657 }
658 }
659
660 private void processInstanceTermination(InstancePortEvent event,
661 InstancePort instPort) {
662 if (!isRelevantHelper(event)) {
663 return;
664 }
665
666 log.info("SwitchingHandler: Instance port terminated MAC:{} IP:{}",
667 instPort.macAddress(),
668 instPort.ipAddress());
669
670 removeVportRules(instPort);
671 }
672
673 private void processInstanceRemoval(InstancePortEvent event,
674 InstancePort instPort) {
675 if (!isRelevantHelper(event)) {
676 return;
677 }
678
679 log.info("SwitchingHandler: Instance port vanished MAC:{} IP:{}",
680 instPort.macAddress(),
681 instPort.ipAddress());
682
683 instPortRemoved(instPort);
684
685 Port osPort = osNetworkService.port(instPort.portId());
686
687 if (osPort != null) {
688 setPortBlockRules(instPort, false);
689 }
690 }
691
692 private void processInstanceMigrationEnd(InstancePortEvent event,
693 InstancePort instPort) {
694 if (!isRelevantHelper(event)) {
695 return;
696 }
697
698 log.info("SwitchingHandler: Migration finished for MAC:{} IP:{}",
699 instPort.macAddress(),
700 instPort.ipAddress());
701
702 InstancePort revisedInstPort = swapStaleLocation(instPort);
703
704 removeVportRules(revisedInstPort);
705 }
706
707 /**
708 * Configures L2 forwarding rules.
Jian Li621f73c2018-12-15 01:49:22 +0900709 * Currently, SONA supports Flat, VXLAN, GRE, GENEVE and VLAN modes.
Jian Li4d138702018-11-27 17:25:28 +0900710 *
711 * @param instPort instance port object
712 * @param install install flag, add the rule if true, remove it otherwise
713 */
714 private void setNetworkRules(InstancePort instPort, boolean install) {
SONA Project6bc5c4a2018-12-14 23:49:52 +0900715 Type type = osNetworkService.networkType(instPort.networkId());
Jian Li4d138702018-11-27 17:25:28 +0900716
717 switch (type) {
718 case VXLAN:
Jian Li2d68c192018-12-13 15:52:59 +0900719 case GRE:
Jian Li621f73c2018-12-15 01:49:22 +0900720 case GENEVE:
Jian Li2d68c192018-12-13 15:52:59 +0900721 setNetworkRulesForTunnel(instPort, install);
Jian Li4d138702018-11-27 17:25:28 +0900722 break;
723 case VLAN:
724 setNetworkRulesForVlan(instPort, install);
725 break;
726 case FLAT:
727 setNetworkRulesForFlat(instPort, install);
728 break;
729 default:
730 log.warn("Unsupported network tunnel type {}", type.name());
731 break;
732 }
733 }
734
Jian Li2d68c192018-12-13 15:52:59 +0900735 private void setNetworkRulesForTunnel(InstancePort instPort, boolean install) {
Jian Li4d138702018-11-27 17:25:28 +0900736 setTunnelTagIpFlowRules(instPort, install);
Jian Li2d68c192018-12-13 15:52:59 +0900737 setForwardingRulesForTunnel(instPort, install);
Jian Li4d138702018-11-27 17:25:28 +0900738
739 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
740 setTunnelTagArpFlowRules(instPort, install);
741 }
742 }
743
744 private void setNetworkRulesForVlan(InstancePort instPort, boolean install) {
745 setVlanTagIpFlowRules(instPort, install);
746 setForwardingRulesForVlan(instPort, install);
747
748 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
749 setVlanTagArpFlowRules(instPort, install);
750 }
751 }
752
753 private void setNetworkRulesForFlat(InstancePort instPort, boolean install) {
754 setFlatJumpRules(instPort, install);
755 setDownstreamRulesForFlat(instPort, install);
756 setUpstreamRulesForFlat(instPort, install);
757 }
758
759 /**
760 * Removes virtual port related flow rules.
761 *
762 * @param instPort instance port
763 */
764 private void removeVportRules(InstancePort instPort) {
SONA Project6bc5c4a2018-12-14 23:49:52 +0900765 Type type = osNetworkService.networkType(instPort.networkId());
Jian Li4d138702018-11-27 17:25:28 +0900766
767 switch (type) {
768 case VXLAN:
Jian Li2d68c192018-12-13 15:52:59 +0900769 case GRE:
Jian Li621f73c2018-12-15 01:49:22 +0900770 case GENEVE:
Jian Li2d68c192018-12-13 15:52:59 +0900771 removeVportRulesForTunnel(instPort);
Jian Li4d138702018-11-27 17:25:28 +0900772 break;
773 case VLAN:
774 removeVportRulesForVlan(instPort);
775 break;
776 case FLAT:
777 removeVportRulesForFlat(instPort);
778 break;
779 default:
780 log.warn("Unsupported network type {}", type.name());
781 break;
782 }
783 }
784
Jian Li2d68c192018-12-13 15:52:59 +0900785 private void removeVportRulesForTunnel(InstancePort instPort) {
Jian Li4d138702018-11-27 17:25:28 +0900786 setTunnelTagIpFlowRules(instPort, false);
787
788 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
789 setTunnelTagArpFlowRules(instPort, false);
790 }
791 }
792
793 private void removeVportRulesForVlan(InstancePort instPort) {
794 setVlanTagIpFlowRules(instPort, false);
795
796 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
797 setVlanTagArpFlowRules(instPort, false);
798 }
799 }
800
801 private void removeVportRulesForFlat(InstancePort instPort) {
802 setFlatJumpRules(instPort, false);
803 setUpstreamRulesForFlat(instPort, false);
804 setDownstreamRulesForFlat(instPort, false);
805 }
806
Hyunsun Moon44aac662017-02-18 02:07:01 +0900807 private void instPortDetected(InstancePort instPort) {
808 setNetworkRules(instPort, true);
809 // TODO add something else if needed
810 }
811
812 private void instPortRemoved(InstancePort instPort) {
813 setNetworkRules(instPort, false);
814 // TODO add something else if needed
815 }
816 }
Jian Li91be8cd2018-07-22 00:44:46 +0900817
818 private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
819
820 @Override
821 public boolean isRelevant(OpenstackNetworkEvent event) {
Jian Li34220ea2018-11-14 01:30:24 +0900822 return event.subject() != null && event.port() != null;
823 }
Jian Li91be8cd2018-07-22 00:44:46 +0900824
Jian Li34220ea2018-11-14 01:30:24 +0900825 private boolean isRelevantHelper() {
826 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
Jian Li91be8cd2018-07-22 00:44:46 +0900827 }
828
829 @Override
830 public void event(OpenstackNetworkEvent event) {
Jian Li91be8cd2018-07-22 00:44:46 +0900831 switch (event.type()) {
832 case OPENSTACK_NETWORK_CREATED:
833 case OPENSTACK_NETWORK_UPDATED:
Jian Li4d138702018-11-27 17:25:28 +0900834 eventExecutor.execute(() -> processNetworkAddition(event));
Jian Li91be8cd2018-07-22 00:44:46 +0900835 break;
836 case OPENSTACK_NETWORK_REMOVED:
Jian Li4d138702018-11-27 17:25:28 +0900837 eventExecutor.execute(() -> processNetworkRemoval(event));
Jian Li91be8cd2018-07-22 00:44:46 +0900838 break;
839 case OPENSTACK_PORT_CREATED:
840 case OPENSTACK_PORT_UPDATED:
Jian Li4d138702018-11-27 17:25:28 +0900841 eventExecutor.execute(() -> processPortAddition(event));
Jian Li91be8cd2018-07-22 00:44:46 +0900842 break;
843 case OPENSTACK_PORT_REMOVED:
Jian Li4d138702018-11-27 17:25:28 +0900844 eventExecutor.execute(() -> processPortRemoval(event));
Jian Li91be8cd2018-07-22 00:44:46 +0900845 break;
846 default:
847 break;
848 }
849 }
Jian Li4d138702018-11-27 17:25:28 +0900850
851 private void processNetworkAddition(OpenstackNetworkEvent event) {
852 if (!isRelevantHelper()) {
853 return;
854 }
855
856 boolean isNwAdminStateUp = event.subject().isAdminStateUp();
857 setNetworkBlockRules(event.subject(), !isNwAdminStateUp);
858 }
859
860 private void processNetworkRemoval(OpenstackNetworkEvent event) {
861 if (!isRelevantHelper()) {
862 return;
863 }
864
865 setNetworkBlockRules(event.subject(), false);
866 }
867
868 private void processPortAddition(OpenstackNetworkEvent event) {
869 if (!isRelevantHelper()) {
870 return;
871 }
872
873 boolean isPortAdminStateUp = event.port().isAdminStateUp();
874 String portId = event.port().getId();
875 InstancePort instPort = instancePortService.instancePort(portId);
876 if (instPort != null) {
877 setPortBlockRules(instPort, !isPortAdminStateUp);
878 }
879 }
880
881 private void processPortRemoval(OpenstackNetworkEvent event) {
882 if (!isRelevantHelper()) {
883 return;
884 }
885
886 String portId = event.port().getId();
887 InstancePort instPort = instancePortService.instancePort(portId);
888 if (instPort != null) {
889 setPortBlockRules(instPort, false);
890 }
891 }
Jian Li91be8cd2018-07-22 00:44:46 +0900892 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900893}