blob: 31750d44eb0efbb703181d83c3c82931387e7c59 [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;
Jian Li91be8cd2018-07-22 00:44:46 +090042import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
43import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
Hyunsun Moon44aac662017-02-18 02:07:01 +090044import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
Hyunsun Moon0d457362017-06-27 17:19:41 +090045import org.onosproject.openstacknode.api.OpenstackNode;
46import org.onosproject.openstacknode.api.OpenstackNodeService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090047import org.openstack4j.model.network.Network;
Frank Wangf9571662017-06-06 18:01:29 +080048import org.openstack4j.model.network.NetworkType;
49import 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;
72import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLAT_JUMP_DOWNSTREAM_RULE;
73import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLAT_JUMP_UPSTREAM_RULE;
74import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLAT_UPSTREAM_RULE;
sanghodc375372017-06-08 10:41:30 +090075import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
76import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_TUNNEL_TAG_RULE;
Jian Li960ae512018-07-03 22:50:56 +090077import static org.onosproject.openstacknetworking.api.Constants.STAT_FLAT_OUTBOUND_TABLE;
Jian Li70a2c3f2018-04-13 17:26:31 +090078import static org.onosproject.openstacknetworking.api.Constants.VTAG_TABLE;
Jian Li34220ea2018-11-14 01:30:24 +090079import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_STARTED;
Jian Li5c09e212018-10-24 18:23:58 +090080import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
Jian Liec5c32b2018-07-13 14:28:58 +090081import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
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 }
191
192 selector = DefaultTrafficSelector.builder();
Daniel Parkd1b14d32018-06-12 16:10:28 +0900193 selector.matchInPort(portNumber)
194 .matchEthType(Ethernet.TYPE_IPV4)
195 .matchIPDst(port.ipAddress().toIpPrefix());
Jian Li70a2c3f2018-04-13 17:26:31 +0900196
197 osFlowRuleService.setRule(
198 appId,
199 port.deviceId(),
200 selector.build(),
201 treatment.build(),
Daniel Parkd1b14d32018-06-12 16:10:28 +0900202 PRIORITY_FLAT_JUMP_DOWNSTREAM_RULE,
Jian Li5c09e212018-10-24 18:23:58 +0900203 DHCP_TABLE,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900204 install);
205
206 selector = DefaultTrafficSelector.builder();
207 selector.matchInPort(portNumber)
208 .matchEthType(Ethernet.TYPE_ARP)
209 .matchArpTpa(port.ipAddress().getIp4Address());
210
211 osFlowRuleService.setRule(
212 appId,
213 port.deviceId(),
214 selector.build(),
215 treatment.build(),
216 PRIORITY_FLAT_JUMP_DOWNSTREAM_RULE,
Jian Li5c09e212018-10-24 18:23:58 +0900217 DHCP_TABLE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900218 install);
219 }
220
Jian Li9a921b42018-06-18 02:44:50 +0900221 private void setDownstreamRulesForFlat(InstancePort instPort, boolean install) {
daniel park796c2eb2018-03-22 17:01:51 +0900222 TrafficSelector selector = DefaultTrafficSelector.builder()
223 .matchEthType(Ethernet.TYPE_IPV4)
224 .matchIPDst(instPort.ipAddress().toIpPrefix())
225 .build();
226 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
227 .setOutput(instPort.portNumber())
228 .build();
229
230 osFlowRuleService.setRule(
231 appId,
232 instPort.deviceId(),
233 selector,
234 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900235 PRIORITY_FLAT_DOWNSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900236 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900237 install);
238
239 selector = DefaultTrafficSelector.builder()
240 .matchEthType(Ethernet.TYPE_ARP)
241 .matchArpTpa(instPort.ipAddress().getIp4Address())
242 .build();
243
244 osFlowRuleService.setRule(
245 appId,
246 instPort.deviceId(),
247 selector,
248 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900249 PRIORITY_FLAT_DOWNSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900250 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900251 install);
252 }
253
Jian Li9a921b42018-06-18 02:44:50 +0900254 private void setUpstreamRulesForFlat(InstancePort instPort, boolean install) {
daniel park796c2eb2018-03-22 17:01:51 +0900255 TrafficSelector selector = DefaultTrafficSelector.builder()
256 .matchInPort(instPort.portNumber())
257 .build();
258
259 Network network = osNetworkService.network(instPort.networkId());
260
261 if (network == null) {
262 log.warn("The network does not exist");
263 return;
264 }
265
266 PortNumber portNumber = osNodeService.node(instPort.deviceId())
267 .phyIntfPortNum(network.getProviderPhyNet());
268
269 if (portNumber == null) {
270 log.warn("The port number does not exist");
271 return;
272 }
273
274 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
275 .setOutput(portNumber)
276 .build();
277
278 osFlowRuleService.setRule(
279 appId,
280 instPort.deviceId(),
281 selector,
282 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900283 PRIORITY_FLAT_UPSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900284 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900285 install);
286 }
287
Jian Liea1b9662018-03-02 18:07:32 +0900288 /**
289 * Configures the flow rules which are used for L2 packet switching.
290 * Note that these rules will be inserted in switching table (table 5).
291 *
292 * @param instPort instance port object
293 * @param install install flag, add the rule if true, remove it otherwise
294 */
Jian Li9a921b42018-06-18 02:44:50 +0900295 private void setForwardingRulesForVxlan(InstancePort instPort, boolean install) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900296 // switching rules for the instPorts in the same node
297 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900298 // TODO: need to handle IPv6 in near future
Hyunsun Moon44aac662017-02-18 02:07:01 +0900299 .matchEthType(Ethernet.TYPE_IPV4)
300 .matchIPDst(instPort.ipAddress().toIpPrefix())
301 .matchTunnelId(getVni(instPort))
302 .build();
303
304 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900305 // TODO: this might not be necessary for the VMs located in the same subnet
Hyunsun Moon44aac662017-02-18 02:07:01 +0900306 .setEthDst(instPort.macAddress())
307 .setOutput(instPort.portNumber())
308 .build();
309
sanghodc375372017-06-08 10:41:30 +0900310 osFlowRuleService.setRule(
Hyunsun Moon44aac662017-02-18 02:07:01 +0900311 appId,
312 instPort.deviceId(),
313 selector,
314 treatment,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900315 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900316 FORWARDING_TABLE,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900317 install);
318
319 // switching rules for the instPorts in the remote node
Hyunsun Moon0d457362017-06-27 17:19:41 +0900320 OpenstackNode localNode = osNodeService.node(instPort.deviceId());
321 if (localNode == null) {
322 final String error = String.format("Cannot find openstack node for %s",
323 instPort.deviceId());
324 throw new IllegalStateException(error);
325 }
326 osNodeService.completeNodes(COMPUTE).stream()
327 .filter(remoteNode -> !remoteNode.intgBridge().equals(localNode.intgBridge()))
328 .forEach(remoteNode -> {
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900329 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
330 .extension(buildExtension(
331 deviceService,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900332 remoteNode.intgBridge(),
333 localNode.dataIp().getIp4Address()),
334 remoteNode.intgBridge())
335 .setOutput(remoteNode.tunnelPortNum())
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900336 .build();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900337
sanghodc375372017-06-08 10:41:30 +0900338 osFlowRuleService.setRule(
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900339 appId,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900340 remoteNode.intgBridge(),
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900341 selector,
342 treatmentToRemote,
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900343 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900344 FORWARDING_TABLE,
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900345 install);
346 });
Hyunsun Moon44aac662017-02-18 02:07:01 +0900347 }
348
Jian Liea1b9662018-03-02 18:07:32 +0900349 /**
350 * Configures the flow rules which are used for L2 VLAN packet switching.
351 * Note that these rules will be inserted in switching table (table 5).
352 *
353 * @param instPort instance port object
354 * @param install install flag, add the rule if true, remove it otherwise
355 */
daniel parka792cf72017-04-14 16:25:35 +0900356 private void setForwardingRulesForVlan(InstancePort instPort, boolean install) {
357 // switching rules for the instPorts in the same node
358 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900359 // TODO: need to handle IPv6 in near future
daniel parka792cf72017-04-14 16:25:35 +0900360 .matchEthType(Ethernet.TYPE_IPV4)
361 .matchIPDst(instPort.ipAddress().toIpPrefix())
362 .matchVlanId(getVlanId(instPort))
363 .build();
364
365 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
366 .popVlan()
Jian Liea1b9662018-03-02 18:07:32 +0900367 // TODO: this might not be necessary for the VMs located in the same subnet
daniel parka792cf72017-04-14 16:25:35 +0900368 .setEthDst(instPort.macAddress())
369 .setOutput(instPort.portNumber())
370 .build();
371
sanghodc375372017-06-08 10:41:30 +0900372 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900373 appId,
374 instPort.deviceId(),
375 selector,
376 treatment,
daniel parka792cf72017-04-14 16:25:35 +0900377 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900378 FORWARDING_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900379 install);
380
381 // switching rules for the instPorts in the remote node
Hyunsun Moon0d457362017-06-27 17:19:41 +0900382 osNodeService.completeNodes(COMPUTE).stream()
383 .filter(remoteNode -> !remoteNode.intgBridge().equals(instPort.deviceId()) &&
384 remoteNode.vlanIntf() != null)
385 .forEach(remoteNode -> {
daniel parka792cf72017-04-14 16:25:35 +0900386 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
Daniel Parkc64b4c62018-05-09 18:13:39 +0900387 .setEthDst(instPort.macAddress())
388 .setOutput(remoteNode.vlanPortNum())
389 .build();
daniel parka792cf72017-04-14 16:25:35 +0900390
sanghodc375372017-06-08 10:41:30 +0900391 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900392 appId,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900393 remoteNode.intgBridge(),
daniel parka792cf72017-04-14 16:25:35 +0900394 selector,
395 treatmentToRemote,
daniel parka792cf72017-04-14 16:25:35 +0900396 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900397 FORWARDING_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900398 install);
399 });
daniel parka792cf72017-04-14 16:25:35 +0900400 }
401
Jian Li5c09e212018-10-24 18:23:58 +0900402 private void setTunnelTagArpFlowRules(InstancePort instPort, boolean install) {
403 setTunnelTagFlowRules(instPort, Ethernet.TYPE_ARP, install);
404 }
405
406 private void setTunnelTagIpFlowRules(InstancePort instPort, boolean install) {
407 setTunnelTagFlowRules(instPort, Ethernet.TYPE_IPV4, install);
408 }
409
Jian Liea1b9662018-03-02 18:07:32 +0900410 /**
411 * Configures the flow rule which is for using VXLAN to tag the packet
412 * based on the in_port number of a virtual instance.
Jian Li5c09e212018-10-24 18:23:58 +0900413 * Note that this rule will be inserted in vTag table.
Jian Liea1b9662018-03-02 18:07:32 +0900414 *
415 * @param instPort instance port object
416 * @param install install flag, add the rule if true, remove it otherwise
417 */
Jian Li5c09e212018-10-24 18:23:58 +0900418 private void setTunnelTagFlowRules(InstancePort instPort,
419 short ethType,
420 boolean install) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900421 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li5c09e212018-10-24 18:23:58 +0900422 .matchEthType(ethType)
Hyunsun Moon44aac662017-02-18 02:07:01 +0900423 .matchInPort(instPort.portNumber())
424 .build();
425
Jian Li28ec77f2018-10-31 07:07:25 +0900426 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
427 .setTunnelId(getVni(instPort));
sangho1aaa7882017-05-31 13:22:47 +0900428
sanghoe6457a32017-08-24 14:31:19 +0900429
Jian Li28ec77f2018-10-31 07:07:25 +0900430 if (ethType == Ethernet.TYPE_ARP) {
431 tBuilder.transition(ARP_TABLE);
432 } else if (ethType == Ethernet.TYPE_IPV4) {
Jian Li1e9cb732018-11-25 23:17:21 +0900433 tBuilder.transition(ACL_EGRESS_TABLE);
sanghoe6457a32017-08-24 14:31:19 +0900434 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900435
sanghodc375372017-06-08 10:41:30 +0900436 osFlowRuleService.setRule(
Hyunsun Moon44aac662017-02-18 02:07:01 +0900437 appId,
438 instPort.deviceId(),
439 selector,
Jian Li28ec77f2018-10-31 07:07:25 +0900440 tBuilder.build(),
Hyunsun Moon44aac662017-02-18 02:07:01 +0900441 PRIORITY_TUNNEL_TAG_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900442 VTAG_TABLE,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900443 install);
444 }
445
Jian Li5c09e212018-10-24 18:23:58 +0900446 private void setVlanTagIpFlowRules(InstancePort instPort, boolean install) {
447 setVlanTagFlowRules(instPort, Ethernet.TYPE_IPV4, install);
448 }
449
450 private void setVlanTagArpFlowRules(InstancePort instPort, boolean install) {
451 setVlanTagFlowRules(instPort, Ethernet.TYPE_ARP, install);
452 }
453
Jian Liea1b9662018-03-02 18:07:32 +0900454 /**
455 * Configures the flow rule which is for using VLAN to tag the packet
456 * based on the in_port number of a virtual instance.
Jian Li5c09e212018-10-24 18:23:58 +0900457 * Note that this rule will be inserted in vTag table.
Jian Liea1b9662018-03-02 18:07:32 +0900458 *
459 * @param instPort instance port object
460 * @param install install flag, add the rule if true, remove it otherwise
461 */
Jian Li5c09e212018-10-24 18:23:58 +0900462 private void setVlanTagFlowRules(InstancePort instPort,
463 short ethType,
464 boolean install) {
daniel parka792cf72017-04-14 16:25:35 +0900465 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li5c09e212018-10-24 18:23:58 +0900466 .matchEthType(ethType)
daniel parka792cf72017-04-14 16:25:35 +0900467 .matchInPort(instPort.portNumber())
468 .build();
469
Daniel Park8a9220f2018-11-19 18:58:35 +0900470 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
daniel parka792cf72017-04-14 16:25:35 +0900471 .pushVlan()
Daniel Park8a9220f2018-11-19 18:58:35 +0900472 .setVlanId(getVlanId(instPort));
473
474 if (ethType == Ethernet.TYPE_ARP) {
475 tBuilder.transition(ARP_TABLE);
476 } else if (ethType == Ethernet.TYPE_IPV4) {
Jian Li1e9cb732018-11-25 23:17:21 +0900477 tBuilder.transition(ACL_EGRESS_TABLE);
Daniel Park8a9220f2018-11-19 18:58:35 +0900478 }
daniel parka792cf72017-04-14 16:25:35 +0900479
sanghodc375372017-06-08 10:41:30 +0900480 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900481 appId,
482 instPort.deviceId(),
483 selector,
Daniel Park8a9220f2018-11-19 18:58:35 +0900484 tBuilder.build(),
daniel parka792cf72017-04-14 16:25:35 +0900485 PRIORITY_TUNNEL_TAG_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900486 VTAG_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900487 install);
daniel parka792cf72017-04-14 16:25:35 +0900488 }
489
Jian Li91be8cd2018-07-22 00:44:46 +0900490 private void setNetworkBlockRules(Network network, boolean install) {
Frank Wangf9571662017-06-06 18:01:29 +0800491
Jian Li91be8cd2018-07-22 00:44:46 +0900492 NetworkType type = network.getNetworkType();
493
494 // TODO: we block a network traffic by referring to segment ID for now
495 // we might need to find a better way to block the traffic of a network
496 // in case the segment ID is overlapped in different types network (VXLAN, VLAN)
497 switch (type) {
498 case VXLAN:
499 setNetworkBlockRulesForVxlan(network.getProviderSegID(), install);
500 break;
501 case VLAN:
502 setNetworkBlockRulesForVlan(network.getProviderSegID(), install);
503 break;
504 case FLAT:
505 // TODO: need to find a way to block flat typed network
506 break;
507 default:
508 break;
Frank Wangf9571662017-06-06 18:01:29 +0800509 }
Jian Li91be8cd2018-07-22 00:44:46 +0900510 }
511
512 private void setNetworkBlockRulesForVxlan(String segmentId, boolean install) {
513 TrafficSelector selector = DefaultTrafficSelector.builder()
514 .matchTunnelId(Long.valueOf(segmentId))
515 .build();
Frank Wangf9571662017-06-06 18:01:29 +0800516
517 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
518 .drop()
519 .build();
520
Jian Li91be8cd2018-07-22 00:44:46 +0900521 osNodeService.completeNodes(COMPUTE)
Jian Liea1b9662018-03-02 18:07:32 +0900522 .forEach(osNode ->
Frank Wangf9571662017-06-06 18:01:29 +0800523 osFlowRuleService.setRule(
Jian Li91be8cd2018-07-22 00:44:46 +0900524 appId,
525 osNode.intgBridge(),
526 selector,
527 treatment,
528 PRIORITY_ADMIN_RULE,
Jian Li1e9cb732018-11-25 23:17:21 +0900529 ACL_EGRESS_TABLE,
Jian Li91be8cd2018-07-22 00:44:46 +0900530 install)
Jian Liea1b9662018-03-02 18:07:32 +0900531 );
Frank Wangf9571662017-06-06 18:01:29 +0800532 }
533
Jian Li91be8cd2018-07-22 00:44:46 +0900534 private void setNetworkBlockRulesForVlan(String segmentId, boolean install) {
Frank Wangf9571662017-06-06 18:01:29 +0800535 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li91be8cd2018-07-22 00:44:46 +0900536 .matchTunnelId(Long.valueOf(segmentId))
537 .build();
538
539 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
540 .drop()
541 .build();
542
543 osNodeService.completeNodes(COMPUTE)
544 .forEach(osNode ->
545 osFlowRuleService.setRule(
546 appId,
547 osNode.intgBridge(),
548 selector,
549 treatment,
550 PRIORITY_ADMIN_RULE,
Jian Li1e9cb732018-11-25 23:17:21 +0900551 ACL_EGRESS_TABLE,
Jian Li91be8cd2018-07-22 00:44:46 +0900552 install)
553 );
554 }
555
556 private void setPortBlockRules(InstancePort instPort, boolean install) {
557 TrafficSelector selector = DefaultTrafficSelector.builder()
558 .matchInPort(instPort.portNumber())
Frank Wangf9571662017-06-06 18:01:29 +0800559 .build();
560
561 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
562 .drop()
563 .build();
564
565 osFlowRuleService.setRule(
566 appId,
Jian Li91be8cd2018-07-22 00:44:46 +0900567 instPort.deviceId(),
Frank Wangf9571662017-06-06 18:01:29 +0800568 selector,
569 treatment,
570 PRIORITY_ADMIN_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900571 VTAG_TABLE,
Frank Wangf9571662017-06-06 18:01:29 +0800572 install);
573 }
574
Jian Liea1b9662018-03-02 18:07:32 +0900575 /**
576 * Obtains the VLAN ID from the given instance port.
577 *
578 * @param instPort instance port object
579 * @return VLAN ID
580 */
daniel parka792cf72017-04-14 16:25:35 +0900581 private VlanId getVlanId(InstancePort instPort) {
582 Network osNet = osNetworkService.network(instPort.networkId());
583
584 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900585 final String error =
586 String.format(ERR_SET_FLOWS_VNI,
Jian Li4d138702018-11-27 17:25:28 +0900587 instPort, osNet == null ? STR_NONE : osNet.getName());
daniel parka792cf72017-04-14 16:25:35 +0900588 throw new IllegalStateException(error);
589 }
590
591 return VlanId.vlanId(osNet.getProviderSegID());
592 }
593
Jian Liea1b9662018-03-02 18:07:32 +0900594 /**
595 * Obtains the VNI from the given instance port.
596 *
597 * @param instPort instance port object
598 * @return VXLAN Network Identifier (VNI)
599 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900600 private Long getVni(InstancePort instPort) {
601 Network osNet = osNetworkService.network(instPort.networkId());
602 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900603 final String error =
604 String.format(ERR_SET_FLOWS_VNI,
Jian Li4d138702018-11-27 17:25:28 +0900605 instPort, osNet == null ? STR_NONE : osNet.getName());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900606 throw new IllegalStateException(error);
607 }
608 return Long.valueOf(osNet.getProviderSegID());
609 }
610
Jian Li5c09e212018-10-24 18:23:58 +0900611 private String getArpMode() {
Jian Li34220ea2018-11-14 01:30:24 +0900612 Set<ConfigProperty> properties =
613 configService.getProperties(OpenstackSwitchingArpHandler.class.getName());
Jian Li5c09e212018-10-24 18:23:58 +0900614 return getPropertyValue(properties, ARP_MODE);
615 }
616
Jian Liea1b9662018-03-02 18:07:32 +0900617 /**
618 * An internal instance port listener which listens the port events generated
619 * from VM. The corresponding L2 forwarding rules will be generated and
620 * inserted to integration bridge only if a new VM port is detected. If the
621 * existing detected VM port is removed due to VM purge, we will remove the
622 * corresponding L2 forwarding to as well for the sake of resource saving.
623 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900624 private class InternalInstancePortListener implements InstancePortListener {
625
Jian Li34220ea2018-11-14 01:30:24 +0900626 private boolean isRelevantHelper(InstancePortEvent event) {
627 return mastershipService.isLocalMaster(event.subject().deviceId());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900628 }
629
630 @Override
631 public void event(InstancePortEvent event) {
632 InstancePort instPort = event.subject();
Jian Li9a921b42018-06-18 02:44:50 +0900633
Hyunsun Moon44aac662017-02-18 02:07:01 +0900634 switch (event.type()) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900635 case OPENSTACK_INSTANCE_PORT_DETECTED:
Jian Liec5c32b2018-07-13 14:28:58 +0900636 case OPENSTACK_INSTANCE_PORT_UPDATED:
Jian Li34220ea2018-11-14 01:30:24 +0900637 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
Jian Li46b74002018-07-15 18:39:08 +0900638 case OPENSTACK_INSTANCE_RESTARTED:
Jian Li4d138702018-11-27 17:25:28 +0900639 eventExecutor.execute(() ->
640 processInstanceDetection(event, instPort));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900641 break;
Jian Li46b74002018-07-15 18:39:08 +0900642 case OPENSTACK_INSTANCE_TERMINATED:
Jian Li4d138702018-11-27 17:25:28 +0900643 eventExecutor.execute(() ->
644 processInstanceTermination(event, instPort));
Jian Li46b74002018-07-15 18:39:08 +0900645 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900646 case OPENSTACK_INSTANCE_PORT_VANISHED:
Jian Li4d138702018-11-27 17:25:28 +0900647 eventExecutor.execute(() ->
648 processInstanceRemoval(event, instPort));
Jian Liec5c32b2018-07-13 14:28:58 +0900649 break;
650 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
Jian Li4d138702018-11-27 17:25:28 +0900651 eventExecutor.execute(() ->
652 processInstanceMigrationEnd(event, instPort));
Jian Li24ec59f2018-05-23 19:01:25 +0900653 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900654 default:
655 break;
656 }
657 }
658
Jian Li4d138702018-11-27 17:25:28 +0900659 private void processInstanceDetection(InstancePortEvent event,
660 InstancePort instPort) {
661 if (!isRelevantHelper(event)) {
662 return;
663 }
664
665 if (event.type() == OPENSTACK_INSTANCE_MIGRATION_STARTED) {
666 log.info("SwitchingHandler: Migration started at MAC:{} IP:{}",
667 instPort.macAddress(),
668 instPort.ipAddress());
669 } else {
670 log.info("SwitchingHandler: Instance port detected MAC:{} IP:{}",
671 instPort.macAddress(),
672 instPort.ipAddress());
673 }
674
675 instPortDetected(instPort);
676
677 Port osPort = osNetworkService.port(instPort.portId());
678
679 if (osPort != null) {
680 setPortBlockRules(instPort, !osPort.isAdminStateUp());
681 }
682 }
683
684 private void processInstanceTermination(InstancePortEvent event,
685 InstancePort instPort) {
686 if (!isRelevantHelper(event)) {
687 return;
688 }
689
690 log.info("SwitchingHandler: Instance port terminated MAC:{} IP:{}",
691 instPort.macAddress(),
692 instPort.ipAddress());
693
694 removeVportRules(instPort);
695 }
696
697 private void processInstanceRemoval(InstancePortEvent event,
698 InstancePort instPort) {
699 if (!isRelevantHelper(event)) {
700 return;
701 }
702
703 log.info("SwitchingHandler: Instance port vanished MAC:{} IP:{}",
704 instPort.macAddress(),
705 instPort.ipAddress());
706
707 instPortRemoved(instPort);
708
709 Port osPort = osNetworkService.port(instPort.portId());
710
711 if (osPort != null) {
712 setPortBlockRules(instPort, false);
713 }
714 }
715
716 private void processInstanceMigrationEnd(InstancePortEvent event,
717 InstancePort instPort) {
718 if (!isRelevantHelper(event)) {
719 return;
720 }
721
722 log.info("SwitchingHandler: Migration finished for MAC:{} IP:{}",
723 instPort.macAddress(),
724 instPort.ipAddress());
725
726 InstancePort revisedInstPort = swapStaleLocation(instPort);
727
728 removeVportRules(revisedInstPort);
729 }
730
731 /**
732 * Configures L2 forwarding rules.
733 * Currently, SONA supports Flat, VXLAN and VLAN modes.
734 *
735 * @param instPort instance port object
736 * @param install install flag, add the rule if true, remove it otherwise
737 */
738 private void setNetworkRules(InstancePort instPort, boolean install) {
739 Network network = osNetworkService.network(instPort.networkId());
740 NetworkType type = network.getNetworkType();
741
742 switch (type) {
743 case VXLAN:
744 setNetworkRulesForVxlan(instPort, install);
745 break;
746 case VLAN:
747 setNetworkRulesForVlan(instPort, install);
748 break;
749 case FLAT:
750 setNetworkRulesForFlat(instPort, install);
751 break;
752 default:
753 log.warn("Unsupported network tunnel type {}", type.name());
754 break;
755 }
756 }
757
758 private void setNetworkRulesForVxlan(InstancePort instPort, boolean install) {
759 setTunnelTagIpFlowRules(instPort, install);
760 setForwardingRulesForVxlan(instPort, install);
761
762 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
763 setTunnelTagArpFlowRules(instPort, install);
764 }
765 }
766
767 private void setNetworkRulesForVlan(InstancePort instPort, boolean install) {
768 setVlanTagIpFlowRules(instPort, install);
769 setForwardingRulesForVlan(instPort, install);
770
771 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
772 setVlanTagArpFlowRules(instPort, install);
773 }
774 }
775
776 private void setNetworkRulesForFlat(InstancePort instPort, boolean install) {
777 setFlatJumpRules(instPort, install);
778 setDownstreamRulesForFlat(instPort, install);
779 setUpstreamRulesForFlat(instPort, install);
780 }
781
782 /**
783 * Removes virtual port related flow rules.
784 *
785 * @param instPort instance port
786 */
787 private void removeVportRules(InstancePort instPort) {
788 Network network = osNetworkService.network(instPort.networkId());
789 NetworkType type = network.getNetworkType();
790
791 switch (type) {
792 case VXLAN:
793 removeVportRulesForVxlan(instPort);
794 break;
795 case VLAN:
796 removeVportRulesForVlan(instPort);
797 break;
798 case FLAT:
799 removeVportRulesForFlat(instPort);
800 break;
801 default:
802 log.warn("Unsupported network type {}", type.name());
803 break;
804 }
805 }
806
807 private void removeVportRulesForVxlan(InstancePort instPort) {
808 setTunnelTagIpFlowRules(instPort, false);
809
810 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
811 setTunnelTagArpFlowRules(instPort, false);
812 }
813 }
814
815 private void removeVportRulesForVlan(InstancePort instPort) {
816 setVlanTagIpFlowRules(instPort, false);
817
818 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
819 setVlanTagArpFlowRules(instPort, false);
820 }
821 }
822
823 private void removeVportRulesForFlat(InstancePort instPort) {
824 setFlatJumpRules(instPort, false);
825 setUpstreamRulesForFlat(instPort, false);
826 setDownstreamRulesForFlat(instPort, false);
827 }
828
Hyunsun Moon44aac662017-02-18 02:07:01 +0900829 private void instPortDetected(InstancePort instPort) {
830 setNetworkRules(instPort, true);
831 // TODO add something else if needed
832 }
833
834 private void instPortRemoved(InstancePort instPort) {
835 setNetworkRules(instPort, false);
836 // TODO add something else if needed
837 }
838 }
Jian Li91be8cd2018-07-22 00:44:46 +0900839
840 private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
841
842 @Override
843 public boolean isRelevant(OpenstackNetworkEvent event) {
Jian Li34220ea2018-11-14 01:30:24 +0900844 return event.subject() != null && event.port() != null;
845 }
Jian Li91be8cd2018-07-22 00:44:46 +0900846
Jian Li34220ea2018-11-14 01:30:24 +0900847 private boolean isRelevantHelper() {
848 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
Jian Li91be8cd2018-07-22 00:44:46 +0900849 }
850
851 @Override
852 public void event(OpenstackNetworkEvent event) {
Jian Li91be8cd2018-07-22 00:44:46 +0900853 switch (event.type()) {
854 case OPENSTACK_NETWORK_CREATED:
855 case OPENSTACK_NETWORK_UPDATED:
Jian Li4d138702018-11-27 17:25:28 +0900856 eventExecutor.execute(() -> processNetworkAddition(event));
Jian Li91be8cd2018-07-22 00:44:46 +0900857 break;
858 case OPENSTACK_NETWORK_REMOVED:
Jian Li4d138702018-11-27 17:25:28 +0900859 eventExecutor.execute(() -> processNetworkRemoval(event));
Jian Li91be8cd2018-07-22 00:44:46 +0900860 break;
861 case OPENSTACK_PORT_CREATED:
862 case OPENSTACK_PORT_UPDATED:
Jian Li4d138702018-11-27 17:25:28 +0900863 eventExecutor.execute(() -> processPortAddition(event));
Jian Li91be8cd2018-07-22 00:44:46 +0900864 break;
865 case OPENSTACK_PORT_REMOVED:
Jian Li4d138702018-11-27 17:25:28 +0900866 eventExecutor.execute(() -> processPortRemoval(event));
Jian Li91be8cd2018-07-22 00:44:46 +0900867 break;
868 default:
869 break;
870 }
871 }
Jian Li4d138702018-11-27 17:25:28 +0900872
873 private void processNetworkAddition(OpenstackNetworkEvent event) {
874 if (!isRelevantHelper()) {
875 return;
876 }
877
878 boolean isNwAdminStateUp = event.subject().isAdminStateUp();
879 setNetworkBlockRules(event.subject(), !isNwAdminStateUp);
880 }
881
882 private void processNetworkRemoval(OpenstackNetworkEvent event) {
883 if (!isRelevantHelper()) {
884 return;
885 }
886
887 setNetworkBlockRules(event.subject(), false);
888 }
889
890 private void processPortAddition(OpenstackNetworkEvent event) {
891 if (!isRelevantHelper()) {
892 return;
893 }
894
895 boolean isPortAdminStateUp = event.port().isAdminStateUp();
896 String portId = event.port().getId();
897 InstancePort instPort = instancePortService.instancePort(portId);
898 if (instPort != null) {
899 setPortBlockRules(instPort, !isPortAdminStateUp);
900 }
901 }
902
903 private void processPortRemoval(OpenstackNetworkEvent event) {
904 if (!isRelevantHelper()) {
905 return;
906 }
907
908 String portId = event.port().getId();
909 InstancePort instPort = instancePortService.instancePort(portId);
910 if (instPort != null) {
911 setPortBlockRules(instPort, false);
912 }
913 }
Jian Li91be8cd2018-07-22 00:44:46 +0900914 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900915}