blob: 14fd5da6834f2effcdbf829a9392e731c6e1f5b3 [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;
sanghodc375372017-06-08 10:41:30 +090063import static org.onosproject.openstacknetworking.api.Constants.ACL_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)
92public final class OpenstackSwitchingHandler {
93
94 private final Logger log = getLogger(getClass());
95
Jian Li5c09e212018-10-24 18:23:58 +090096 private static final String ARP_MODE = "arpMode";
Jian Li71670d12018-03-02 21:31:07 +090097 private static final String ERR_SET_FLOWS_VNI = "Failed to set flows for %s: Failed to get VNI for %s";
Hyunsun Moon44aac662017-02-18 02:07:01 +090098
Ray Milkeyd84f89b2018-08-17 14:54:17 -070099 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900100 protected CoreService coreService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900101
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700102 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900103 protected MastershipService mastershipService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900104
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700105 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900106 protected DeviceService deviceService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900107
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700108 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li91be8cd2018-07-22 00:44:46 +0900109 protected DriverService driverService;
110
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700111 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li91be8cd2018-07-22 00:44:46 +0900112 protected ClusterService clusterService;
113
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700114 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li5c09e212018-10-24 18:23:58 +0900115 protected ComponentConfigService configService;
116
Ray Milkey956bb162018-10-26 10:53:44 -0700117 @Reference(cardinality = ReferenceCardinality.MANDATORY)
118
Jian Li91be8cd2018-07-22 00:44:46 +0900119 protected LeadershipService leadershipService;
120
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700121 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900122 protected OpenstackFlowRuleService osFlowRuleService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900123
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700124 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900125 protected InstancePortService instancePortService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900126
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700127 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900128 protected OpenstackNetworkService osNetworkService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900129
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700130 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liea1b9662018-03-02 18:07:32 +0900131 protected OpenstackNodeService osNodeService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900132
133 private final ExecutorService eventExecutor = newSingleThreadExecutor(
134 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
135 private final InstancePortListener instancePortListener = new InternalInstancePortListener();
Jian Li91be8cd2018-07-22 00:44:46 +0900136 private final InternalOpenstackNetworkListener osNetworkListener =
137 new InternalOpenstackNetworkListener();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900138 private ApplicationId appId;
Jian Li91be8cd2018-07-22 00:44:46 +0900139 private NodeId localNodeId;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900140
141 @Activate
Ray Milkey9c9cde42018-01-12 14:22:06 -0800142 void activate() {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900143 appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
Jian Li91be8cd2018-07-22 00:44:46 +0900144 localNodeId = clusterService.getLocalNode().id();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900145 instancePortService.addListener(instancePortListener);
Jian Li91be8cd2018-07-22 00:44:46 +0900146 osNetworkService.addListener(osNetworkListener);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900147
148 log.info("Started");
149 }
150
151 @Deactivate
Ray Milkey9c9cde42018-01-12 14:22:06 -0800152 void deactivate() {
Jian Li91be8cd2018-07-22 00:44:46 +0900153 osNetworkService.removeListener(osNetworkListener);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900154 instancePortService.removeListener(instancePortListener);
155 eventExecutor.shutdown();
156
157 log.info("Stopped");
158 }
159
Jian Liea1b9662018-03-02 18:07:32 +0900160 /**
161 * Configures L2 forwarding rules.
daniel park796c2eb2018-03-22 17:01:51 +0900162 * Currently, SONA supports Flat, VXLAN and VLAN modes.
Jian Liea1b9662018-03-02 18:07:32 +0900163 *
164 * @param instPort instance port object
165 * @param install install flag, add the rule if true, remove it otherwise
166 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900167 private void setNetworkRules(InstancePort instPort, boolean install) {
Jian Liea1b9662018-03-02 18:07:32 +0900168 NetworkType type = osNetworkService.network(instPort.networkId()).getNetworkType();
169 switch (type) {
daniel parka792cf72017-04-14 16:25:35 +0900170 case VXLAN:
Jian Li5c09e212018-10-24 18:23:58 +0900171 setTunnelTagIpFlowRules(instPort, install);
Jian Li9a921b42018-06-18 02:44:50 +0900172 setForwardingRulesForVxlan(instPort, install);
Jian Li5c09e212018-10-24 18:23:58 +0900173
174 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
175 setTunnelTagArpFlowRules(instPort, install);
176 }
177
daniel parka792cf72017-04-14 16:25:35 +0900178 break;
179 case VLAN:
Jian Li5c09e212018-10-24 18:23:58 +0900180 setVlanTagIpFlowRules(instPort, install);
daniel parka792cf72017-04-14 16:25:35 +0900181 setForwardingRulesForVlan(instPort, install);
Jian Li5c09e212018-10-24 18:23:58 +0900182
183 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
184 setVlanTagArpFlowRules(instPort, install);
185 }
186
daniel parka792cf72017-04-14 16:25:35 +0900187 break;
daniel park796c2eb2018-03-22 17:01:51 +0900188 case FLAT:
Jian Li70a2c3f2018-04-13 17:26:31 +0900189 setFlatJumpRules(instPort, install);
Jian Li9a921b42018-06-18 02:44:50 +0900190 setDownstreamRulesForFlat(instPort, install);
191 setUpstreamRulesForFlat(instPort, install);
daniel park796c2eb2018-03-22 17:01:51 +0900192 break;
daniel parka792cf72017-04-14 16:25:35 +0900193 default:
Jian Liea1b9662018-03-02 18:07:32 +0900194 log.warn("Unsupported network tunnel type {}", type.name());
daniel parka792cf72017-04-14 16:25:35 +0900195 break;
196 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900197 }
198
Jian Li24ec59f2018-05-23 19:01:25 +0900199 /**
200 * Removes virtual port.
201 *
202 * @param instPort instance port
203 */
204 private void removeVportRules(InstancePort instPort) {
205 NetworkType type = osNetworkService.network(instPort.networkId()).getNetworkType();
206
207 switch (type) {
208 case VXLAN:
Jian Li5c09e212018-10-24 18:23:58 +0900209 setTunnelTagIpFlowRules(instPort, false);
210
211 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
212 setTunnelTagArpFlowRules(instPort, false);
213 }
214
Jian Li24ec59f2018-05-23 19:01:25 +0900215 break;
216 case VLAN:
Jian Li5c09e212018-10-24 18:23:58 +0900217 setVlanTagIpFlowRules(instPort, false);
218
219 if (ARP_BROADCAST_MODE.equals(getArpMode())) {
220 setVlanTagArpFlowRules(instPort, false);
221 }
222
Jian Li24ec59f2018-05-23 19:01:25 +0900223 break;
Jian Li9a921b42018-06-18 02:44:50 +0900224 case FLAT:
225 setFlatJumpRules(instPort, false);
226 setUpstreamRulesForFlat(instPort, false);
227 setDownstreamRulesForFlat(instPort, false);
Ray Milkeybcc53d32018-07-02 10:22:57 -0700228 break;
Jian Li24ec59f2018-05-23 19:01:25 +0900229 default:
Jian Li9a921b42018-06-18 02:44:50 +0900230 log.warn("Unsupported network type {}", type.name());
Jian Li24ec59f2018-05-23 19:01:25 +0900231 break;
232 }
233 }
234
Jian Li70a2c3f2018-04-13 17:26:31 +0900235 private void setFlatJumpRules(InstancePort port, boolean install) {
236 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
237 selector.matchInPort(port.portNumber());
238
239 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Jian Li960ae512018-07-03 22:50:56 +0900240 treatment.transition(STAT_FLAT_OUTBOUND_TABLE);
Jian Li70a2c3f2018-04-13 17:26:31 +0900241
242 osFlowRuleService.setRule(
243 appId,
244 port.deviceId(),
245 selector.build(),
246 treatment.build(),
Daniel Parkd1b14d32018-06-12 16:10:28 +0900247 PRIORITY_FLAT_JUMP_UPSTREAM_RULE,
Jian Li5c09e212018-10-24 18:23:58 +0900248 DHCP_TABLE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900249 install);
250
251 Network network = osNetworkService.network(port.networkId());
252
253 if (network == null) {
254 log.warn("The network does not exist");
255 return;
256 }
Jian Li70a2c3f2018-04-13 17:26:31 +0900257 PortNumber portNumber = osNodeService.node(port.deviceId())
258 .phyIntfPortNum(network.getProviderPhyNet());
259
260 if (portNumber == null) {
261 log.warn("The port number does not exist");
262 return;
263 }
264
265 selector = DefaultTrafficSelector.builder();
Daniel Parkd1b14d32018-06-12 16:10:28 +0900266 selector.matchInPort(portNumber)
267 .matchEthType(Ethernet.TYPE_IPV4)
268 .matchIPDst(port.ipAddress().toIpPrefix());
Jian Li70a2c3f2018-04-13 17:26:31 +0900269
270 osFlowRuleService.setRule(
271 appId,
272 port.deviceId(),
273 selector.build(),
274 treatment.build(),
Daniel Parkd1b14d32018-06-12 16:10:28 +0900275 PRIORITY_FLAT_JUMP_DOWNSTREAM_RULE,
Jian Li5c09e212018-10-24 18:23:58 +0900276 DHCP_TABLE,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900277 install);
278
279 selector = DefaultTrafficSelector.builder();
280 selector.matchInPort(portNumber)
281 .matchEthType(Ethernet.TYPE_ARP)
282 .matchArpTpa(port.ipAddress().getIp4Address());
283
284 osFlowRuleService.setRule(
285 appId,
286 port.deviceId(),
287 selector.build(),
288 treatment.build(),
289 PRIORITY_FLAT_JUMP_DOWNSTREAM_RULE,
Jian Li5c09e212018-10-24 18:23:58 +0900290 DHCP_TABLE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900291 install);
292 }
293
Jian Li9a921b42018-06-18 02:44:50 +0900294 private void setDownstreamRulesForFlat(InstancePort instPort, boolean install) {
daniel park796c2eb2018-03-22 17:01:51 +0900295 TrafficSelector selector = DefaultTrafficSelector.builder()
296 .matchEthType(Ethernet.TYPE_IPV4)
297 .matchIPDst(instPort.ipAddress().toIpPrefix())
298 .build();
299 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
300 .setOutput(instPort.portNumber())
301 .build();
302
303 osFlowRuleService.setRule(
304 appId,
305 instPort.deviceId(),
306 selector,
307 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900308 PRIORITY_FLAT_DOWNSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900309 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900310 install);
311
312 selector = DefaultTrafficSelector.builder()
313 .matchEthType(Ethernet.TYPE_ARP)
314 .matchArpTpa(instPort.ipAddress().getIp4Address())
315 .build();
316
317 osFlowRuleService.setRule(
318 appId,
319 instPort.deviceId(),
320 selector,
321 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900322 PRIORITY_FLAT_DOWNSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900323 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900324 install);
325 }
326
Jian Li9a921b42018-06-18 02:44:50 +0900327 private void setUpstreamRulesForFlat(InstancePort instPort, boolean install) {
daniel park796c2eb2018-03-22 17:01:51 +0900328 TrafficSelector selector = DefaultTrafficSelector.builder()
329 .matchInPort(instPort.portNumber())
330 .build();
331
332 Network network = osNetworkService.network(instPort.networkId());
333
334 if (network == null) {
335 log.warn("The network does not exist");
336 return;
337 }
338
339 PortNumber portNumber = osNodeService.node(instPort.deviceId())
340 .phyIntfPortNum(network.getProviderPhyNet());
341
342 if (portNumber == null) {
343 log.warn("The port number does not exist");
344 return;
345 }
346
347 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
348 .setOutput(portNumber)
349 .build();
350
351 osFlowRuleService.setRule(
352 appId,
353 instPort.deviceId(),
354 selector,
355 treatment,
Daniel Parkd1b14d32018-06-12 16:10:28 +0900356 PRIORITY_FLAT_UPSTREAM_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900357 FLAT_TABLE,
daniel park796c2eb2018-03-22 17:01:51 +0900358 install);
359 }
360
Jian Liea1b9662018-03-02 18:07:32 +0900361 /**
362 * Configures the flow rules which are used for L2 packet switching.
363 * Note that these rules will be inserted in switching table (table 5).
364 *
365 * @param instPort instance port object
366 * @param install install flag, add the rule if true, remove it otherwise
367 */
Jian Li9a921b42018-06-18 02:44:50 +0900368 private void setForwardingRulesForVxlan(InstancePort instPort, boolean install) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900369 // switching rules for the instPorts in the same node
370 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900371 // TODO: need to handle IPv6 in near future
Hyunsun Moon44aac662017-02-18 02:07:01 +0900372 .matchEthType(Ethernet.TYPE_IPV4)
373 .matchIPDst(instPort.ipAddress().toIpPrefix())
374 .matchTunnelId(getVni(instPort))
375 .build();
376
377 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900378 // TODO: this might not be necessary for the VMs located in the same subnet
Hyunsun Moon44aac662017-02-18 02:07:01 +0900379 .setEthDst(instPort.macAddress())
380 .setOutput(instPort.portNumber())
381 .build();
382
sanghodc375372017-06-08 10:41:30 +0900383 osFlowRuleService.setRule(
Hyunsun Moon44aac662017-02-18 02:07:01 +0900384 appId,
385 instPort.deviceId(),
386 selector,
387 treatment,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900388 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900389 FORWARDING_TABLE,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900390 install);
391
392 // switching rules for the instPorts in the remote node
Hyunsun Moon0d457362017-06-27 17:19:41 +0900393 OpenstackNode localNode = osNodeService.node(instPort.deviceId());
394 if (localNode == null) {
395 final String error = String.format("Cannot find openstack node for %s",
396 instPort.deviceId());
397 throw new IllegalStateException(error);
398 }
399 osNodeService.completeNodes(COMPUTE).stream()
400 .filter(remoteNode -> !remoteNode.intgBridge().equals(localNode.intgBridge()))
401 .forEach(remoteNode -> {
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900402 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
403 .extension(buildExtension(
404 deviceService,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900405 remoteNode.intgBridge(),
406 localNode.dataIp().getIp4Address()),
407 remoteNode.intgBridge())
408 .setOutput(remoteNode.tunnelPortNum())
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900409 .build();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900410
sanghodc375372017-06-08 10:41:30 +0900411 osFlowRuleService.setRule(
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900412 appId,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900413 remoteNode.intgBridge(),
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900414 selector,
415 treatmentToRemote,
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900416 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900417 FORWARDING_TABLE,
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900418 install);
419 });
Hyunsun Moon44aac662017-02-18 02:07:01 +0900420 }
421
Jian Liea1b9662018-03-02 18:07:32 +0900422 /**
423 * Configures the flow rules which are used for L2 VLAN packet switching.
424 * Note that these rules will be inserted in switching table (table 5).
425 *
426 * @param instPort instance port object
427 * @param install install flag, add the rule if true, remove it otherwise
428 */
daniel parka792cf72017-04-14 16:25:35 +0900429 private void setForwardingRulesForVlan(InstancePort instPort, boolean install) {
430 // switching rules for the instPorts in the same node
431 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900432 // TODO: need to handle IPv6 in near future
daniel parka792cf72017-04-14 16:25:35 +0900433 .matchEthType(Ethernet.TYPE_IPV4)
434 .matchIPDst(instPort.ipAddress().toIpPrefix())
435 .matchVlanId(getVlanId(instPort))
436 .build();
437
438 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
439 .popVlan()
Jian Liea1b9662018-03-02 18:07:32 +0900440 // TODO: this might not be necessary for the VMs located in the same subnet
daniel parka792cf72017-04-14 16:25:35 +0900441 .setEthDst(instPort.macAddress())
442 .setOutput(instPort.portNumber())
443 .build();
444
sanghodc375372017-06-08 10:41:30 +0900445 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900446 appId,
447 instPort.deviceId(),
448 selector,
449 treatment,
daniel parka792cf72017-04-14 16:25:35 +0900450 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900451 FORWARDING_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900452 install);
453
454 // switching rules for the instPorts in the remote node
Hyunsun Moon0d457362017-06-27 17:19:41 +0900455 osNodeService.completeNodes(COMPUTE).stream()
456 .filter(remoteNode -> !remoteNode.intgBridge().equals(instPort.deviceId()) &&
457 remoteNode.vlanIntf() != null)
458 .forEach(remoteNode -> {
daniel parka792cf72017-04-14 16:25:35 +0900459 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
Daniel Parkc64b4c62018-05-09 18:13:39 +0900460 .setEthDst(instPort.macAddress())
461 .setOutput(remoteNode.vlanPortNum())
462 .build();
daniel parka792cf72017-04-14 16:25:35 +0900463
sanghodc375372017-06-08 10:41:30 +0900464 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900465 appId,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900466 remoteNode.intgBridge(),
daniel parka792cf72017-04-14 16:25:35 +0900467 selector,
468 treatmentToRemote,
daniel parka792cf72017-04-14 16:25:35 +0900469 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900470 FORWARDING_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900471 install);
472 });
daniel parka792cf72017-04-14 16:25:35 +0900473 }
474
Jian Li5c09e212018-10-24 18:23:58 +0900475 private void setTunnelTagArpFlowRules(InstancePort instPort, boolean install) {
476 setTunnelTagFlowRules(instPort, Ethernet.TYPE_ARP, install);
477 }
478
479 private void setTunnelTagIpFlowRules(InstancePort instPort, boolean install) {
480 setTunnelTagFlowRules(instPort, Ethernet.TYPE_IPV4, install);
481 }
482
Jian Liea1b9662018-03-02 18:07:32 +0900483 /**
484 * Configures the flow rule which is for using VXLAN to tag the packet
485 * based on the in_port number of a virtual instance.
Jian Li5c09e212018-10-24 18:23:58 +0900486 * Note that this rule will be inserted in vTag table.
Jian Liea1b9662018-03-02 18:07:32 +0900487 *
488 * @param instPort instance port object
489 * @param install install flag, add the rule if true, remove it otherwise
490 */
Jian Li5c09e212018-10-24 18:23:58 +0900491 private void setTunnelTagFlowRules(InstancePort instPort,
492 short ethType,
493 boolean install) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900494 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li5c09e212018-10-24 18:23:58 +0900495 .matchEthType(ethType)
Hyunsun Moon44aac662017-02-18 02:07:01 +0900496 .matchInPort(instPort.portNumber())
497 .build();
498
Jian Li28ec77f2018-10-31 07:07:25 +0900499 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
500 .setTunnelId(getVni(instPort));
sangho1aaa7882017-05-31 13:22:47 +0900501
sanghoe6457a32017-08-24 14:31:19 +0900502
Jian Li28ec77f2018-10-31 07:07:25 +0900503 if (ethType == Ethernet.TYPE_ARP) {
504 tBuilder.transition(ARP_TABLE);
505 } else if (ethType == Ethernet.TYPE_IPV4) {
506 tBuilder.transition(ACL_TABLE);
sanghoe6457a32017-08-24 14:31:19 +0900507 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900508
sanghodc375372017-06-08 10:41:30 +0900509 osFlowRuleService.setRule(
Hyunsun Moon44aac662017-02-18 02:07:01 +0900510 appId,
511 instPort.deviceId(),
512 selector,
Jian Li28ec77f2018-10-31 07:07:25 +0900513 tBuilder.build(),
Hyunsun Moon44aac662017-02-18 02:07:01 +0900514 PRIORITY_TUNNEL_TAG_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900515 VTAG_TABLE,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900516 install);
517 }
518
Jian Li5c09e212018-10-24 18:23:58 +0900519 private void setVlanTagIpFlowRules(InstancePort instPort, boolean install) {
520 setVlanTagFlowRules(instPort, Ethernet.TYPE_IPV4, install);
521 }
522
523 private void setVlanTagArpFlowRules(InstancePort instPort, boolean install) {
524 setVlanTagFlowRules(instPort, Ethernet.TYPE_ARP, install);
525 }
526
Jian Liea1b9662018-03-02 18:07:32 +0900527 /**
528 * Configures the flow rule which is for using VLAN to tag the packet
529 * based on the in_port number of a virtual instance.
Jian Li5c09e212018-10-24 18:23:58 +0900530 * Note that this rule will be inserted in vTag table.
Jian Liea1b9662018-03-02 18:07:32 +0900531 *
532 * @param instPort instance port object
533 * @param install install flag, add the rule if true, remove it otherwise
534 */
Jian Li5c09e212018-10-24 18:23:58 +0900535 private void setVlanTagFlowRules(InstancePort instPort,
536 short ethType,
537 boolean install) {
daniel parka792cf72017-04-14 16:25:35 +0900538 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li5c09e212018-10-24 18:23:58 +0900539 .matchEthType(ethType)
daniel parka792cf72017-04-14 16:25:35 +0900540 .matchInPort(instPort.portNumber())
541 .build();
542
543 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
544 .pushVlan()
545 .setVlanId(getVlanId(instPort))
sanghodc375372017-06-08 10:41:30 +0900546 .transition(ACL_TABLE)
daniel parka792cf72017-04-14 16:25:35 +0900547 .build();
548
sanghodc375372017-06-08 10:41:30 +0900549 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900550 appId,
551 instPort.deviceId(),
552 selector,
553 treatment,
daniel parka792cf72017-04-14 16:25:35 +0900554 PRIORITY_TUNNEL_TAG_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900555 VTAG_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900556 install);
daniel parka792cf72017-04-14 16:25:35 +0900557 }
558
Jian Li91be8cd2018-07-22 00:44:46 +0900559 private void setNetworkBlockRules(Network network, boolean install) {
Frank Wangf9571662017-06-06 18:01:29 +0800560
Jian Li91be8cd2018-07-22 00:44:46 +0900561 NetworkType type = network.getNetworkType();
562
563 // TODO: we block a network traffic by referring to segment ID for now
564 // we might need to find a better way to block the traffic of a network
565 // in case the segment ID is overlapped in different types network (VXLAN, VLAN)
566 switch (type) {
567 case VXLAN:
568 setNetworkBlockRulesForVxlan(network.getProviderSegID(), install);
569 break;
570 case VLAN:
571 setNetworkBlockRulesForVlan(network.getProviderSegID(), install);
572 break;
573 case FLAT:
574 // TODO: need to find a way to block flat typed network
575 break;
576 default:
577 break;
Frank Wangf9571662017-06-06 18:01:29 +0800578 }
Jian Li91be8cd2018-07-22 00:44:46 +0900579 }
580
581 private void setNetworkBlockRulesForVxlan(String segmentId, boolean install) {
582 TrafficSelector selector = DefaultTrafficSelector.builder()
583 .matchTunnelId(Long.valueOf(segmentId))
584 .build();
Frank Wangf9571662017-06-06 18:01:29 +0800585
586 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
587 .drop()
588 .build();
589
Jian Li91be8cd2018-07-22 00:44:46 +0900590 osNodeService.completeNodes(COMPUTE)
Jian Liea1b9662018-03-02 18:07:32 +0900591 .forEach(osNode ->
Frank Wangf9571662017-06-06 18:01:29 +0800592 osFlowRuleService.setRule(
Jian Li91be8cd2018-07-22 00:44:46 +0900593 appId,
594 osNode.intgBridge(),
595 selector,
596 treatment,
597 PRIORITY_ADMIN_RULE,
598 ACL_TABLE,
599 install)
Jian Liea1b9662018-03-02 18:07:32 +0900600 );
Frank Wangf9571662017-06-06 18:01:29 +0800601 }
602
Jian Li91be8cd2018-07-22 00:44:46 +0900603 private void setNetworkBlockRulesForVlan(String segmentId, boolean install) {
Frank Wangf9571662017-06-06 18:01:29 +0800604 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li91be8cd2018-07-22 00:44:46 +0900605 .matchTunnelId(Long.valueOf(segmentId))
606 .build();
607
608 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
609 .drop()
610 .build();
611
612 osNodeService.completeNodes(COMPUTE)
613 .forEach(osNode ->
614 osFlowRuleService.setRule(
615 appId,
616 osNode.intgBridge(),
617 selector,
618 treatment,
619 PRIORITY_ADMIN_RULE,
620 ACL_TABLE,
621 install)
622 );
623 }
624
625 private void setPortBlockRules(InstancePort instPort, boolean install) {
626 TrafficSelector selector = DefaultTrafficSelector.builder()
627 .matchInPort(instPort.portNumber())
Frank Wangf9571662017-06-06 18:01:29 +0800628 .build();
629
630 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
631 .drop()
632 .build();
633
634 osFlowRuleService.setRule(
635 appId,
Jian Li91be8cd2018-07-22 00:44:46 +0900636 instPort.deviceId(),
Frank Wangf9571662017-06-06 18:01:29 +0800637 selector,
638 treatment,
639 PRIORITY_ADMIN_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900640 VTAG_TABLE,
Frank Wangf9571662017-06-06 18:01:29 +0800641 install);
642 }
643
Jian Liea1b9662018-03-02 18:07:32 +0900644 /**
645 * Obtains the VLAN ID from the given instance port.
646 *
647 * @param instPort instance port object
648 * @return VLAN ID
649 */
daniel parka792cf72017-04-14 16:25:35 +0900650 private VlanId getVlanId(InstancePort instPort) {
651 Network osNet = osNetworkService.network(instPort.networkId());
652
653 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900654 final String error =
655 String.format(ERR_SET_FLOWS_VNI,
656 instPort, osNet == null ? "<none>" : osNet.getName());
daniel parka792cf72017-04-14 16:25:35 +0900657 throw new IllegalStateException(error);
658 }
659
660 return VlanId.vlanId(osNet.getProviderSegID());
661 }
662
Jian Liea1b9662018-03-02 18:07:32 +0900663 /**
664 * Obtains the VNI from the given instance port.
665 *
666 * @param instPort instance port object
667 * @return VXLAN Network Identifier (VNI)
668 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900669 private Long getVni(InstancePort instPort) {
670 Network osNet = osNetworkService.network(instPort.networkId());
671 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900672 final String error =
673 String.format(ERR_SET_FLOWS_VNI,
674 instPort, osNet == null ? "<none>" : osNet.getName());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900675 throw new IllegalStateException(error);
676 }
677 return Long.valueOf(osNet.getProviderSegID());
678 }
679
Jian Li5c09e212018-10-24 18:23:58 +0900680 private String getArpMode() {
Jian Li34220ea2018-11-14 01:30:24 +0900681 Set<ConfigProperty> properties =
682 configService.getProperties(OpenstackSwitchingArpHandler.class.getName());
Jian Li5c09e212018-10-24 18:23:58 +0900683 return getPropertyValue(properties, ARP_MODE);
684 }
685
Jian Liea1b9662018-03-02 18:07:32 +0900686 /**
687 * An internal instance port listener which listens the port events generated
688 * from VM. The corresponding L2 forwarding rules will be generated and
689 * inserted to integration bridge only if a new VM port is detected. If the
690 * existing detected VM port is removed due to VM purge, we will remove the
691 * corresponding L2 forwarding to as well for the sake of resource saving.
692 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900693 private class InternalInstancePortListener implements InstancePortListener {
694
Jian Li34220ea2018-11-14 01:30:24 +0900695 private boolean isRelevantHelper(InstancePortEvent event) {
696 return mastershipService.isLocalMaster(event.subject().deviceId());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900697 }
698
699 @Override
700 public void event(InstancePortEvent event) {
701 InstancePort instPort = event.subject();
Jian Li9a921b42018-06-18 02:44:50 +0900702
Hyunsun Moon44aac662017-02-18 02:07:01 +0900703 switch (event.type()) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900704 case OPENSTACK_INSTANCE_PORT_DETECTED:
Jian Liec5c32b2018-07-13 14:28:58 +0900705 case OPENSTACK_INSTANCE_PORT_UPDATED:
Jian Li34220ea2018-11-14 01:30:24 +0900706 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
Jian Li46b74002018-07-15 18:39:08 +0900707 case OPENSTACK_INSTANCE_RESTARTED:
Jian Li34220ea2018-11-14 01:30:24 +0900708
709 if (event.type() == OPENSTACK_INSTANCE_MIGRATION_STARTED) {
710 log.info("SwitchingHandler: Migration started at MAC:{} IP:{}",
Jian Li9a921b42018-06-18 02:44:50 +0900711 instPort.macAddress(),
712 instPort.ipAddress());
Jian Li34220ea2018-11-14 01:30:24 +0900713 } else {
714 log.info("SwitchingHandler: Instance port detected MAC:{} IP:{}",
715 instPort.macAddress(),
716 instPort.ipAddress());
Jian Li91be8cd2018-07-22 00:44:46 +0900717 }
718
Jian Li34220ea2018-11-14 01:30:24 +0900719 eventExecutor.execute(() -> {
720
721 if (!isRelevantHelper(event)) {
722 return;
723 }
724
725 instPortDetected(instPort);
726
727 Port osPort = osNetworkService.port(instPort.portId());
728
729 if (osPort != null) {
730 setPortBlockRules(instPort, !osPort.isAdminStateUp());
731 }
732 });
733
Hyunsun Moon44aac662017-02-18 02:07:01 +0900734 break;
Jian Li46b74002018-07-15 18:39:08 +0900735 case OPENSTACK_INSTANCE_TERMINATED:
736 log.info("SwitchingHandler: Instance port terminated MAC:{} IP:{}",
737 instPort.macAddress(),
738 instPort.ipAddress());
Jian Li34220ea2018-11-14 01:30:24 +0900739 eventExecutor.execute(() -> {
740
741 if (!isRelevantHelper(event)) {
742 return;
743 }
744
745 removeVportRules(instPort);
746 });
Jian Li46b74002018-07-15 18:39:08 +0900747
748 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900749 case OPENSTACK_INSTANCE_PORT_VANISHED:
Jian Liec5c32b2018-07-13 14:28:58 +0900750 log.info("SwitchingHandler: Instance port vanished MAC:{} IP:{}",
Jian Li9a921b42018-06-18 02:44:50 +0900751 instPort.macAddress(),
752 instPort.ipAddress());
Jian Liec5c32b2018-07-13 14:28:58 +0900753
Jian Li34220ea2018-11-14 01:30:24 +0900754 eventExecutor.execute(() -> {
Jian Li9a921b42018-06-18 02:44:50 +0900755
Jian Li34220ea2018-11-14 01:30:24 +0900756 if (!isRelevantHelper(event)) {
757 return;
758 }
Jian Li91be8cd2018-07-22 00:44:46 +0900759
Jian Li34220ea2018-11-14 01:30:24 +0900760 instPortRemoved(instPort);
Jian Liec5c32b2018-07-13 14:28:58 +0900761
Jian Li34220ea2018-11-14 01:30:24 +0900762 Port osPort = osNetworkService.port(instPort.portId());
Jian Liec5c32b2018-07-13 14:28:58 +0900763
Jian Li34220ea2018-11-14 01:30:24 +0900764 if (osPort != null) {
765 setPortBlockRules(instPort, false);
766 }
767 });
Jian Li91be8cd2018-07-22 00:44:46 +0900768
Jian Liec5c32b2018-07-13 14:28:58 +0900769 break;
770 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
771 log.info("SwitchingHandler: Migration finished for MAC:{} IP:{}",
772 instPort.macAddress(),
773 instPort.ipAddress());
774
775 InstancePort revisedInstPort = swapStaleLocation(instPort);
Jian Li34220ea2018-11-14 01:30:24 +0900776 eventExecutor.execute(() -> {
777
778 if (!isRelevantHelper(event)) {
779 return;
780 }
781
782 removeVportRules(revisedInstPort);
783 });
Jian Liec5c32b2018-07-13 14:28:58 +0900784
Jian Li24ec59f2018-05-23 19:01:25 +0900785 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900786 default:
787 break;
788 }
789 }
790
791 private void instPortDetected(InstancePort instPort) {
792 setNetworkRules(instPort, true);
793 // TODO add something else if needed
794 }
795
796 private void instPortRemoved(InstancePort instPort) {
797 setNetworkRules(instPort, false);
798 // TODO add something else if needed
799 }
800 }
Jian Li91be8cd2018-07-22 00:44:46 +0900801
802 private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
803
804 @Override
805 public boolean isRelevant(OpenstackNetworkEvent event) {
Jian Li34220ea2018-11-14 01:30:24 +0900806 return event.subject() != null && event.port() != null;
807 }
Jian Li91be8cd2018-07-22 00:44:46 +0900808
Jian Li34220ea2018-11-14 01:30:24 +0900809 private boolean isRelevantHelper() {
810 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
Jian Li91be8cd2018-07-22 00:44:46 +0900811 }
812
813 @Override
814 public void event(OpenstackNetworkEvent event) {
815
Jian Li91be8cd2018-07-22 00:44:46 +0900816 boolean isNwAdminStateUp = event.subject().isAdminStateUp();
817 boolean isPortAdminStateUp = event.port().isAdminStateUp();
818
Jian Li32b03622018-11-06 17:54:24 +0900819 String portId = event.port().getId();
Jian Li91be8cd2018-07-22 00:44:46 +0900820
821 switch (event.type()) {
822 case OPENSTACK_NETWORK_CREATED:
823 case OPENSTACK_NETWORK_UPDATED:
Jian Li34220ea2018-11-14 01:30:24 +0900824 eventExecutor.execute(() -> {
Jian Li91be8cd2018-07-22 00:44:46 +0900825
Jian Li34220ea2018-11-14 01:30:24 +0900826 if (!isRelevantHelper()) {
827 return;
828 }
829
830 setNetworkBlockRules(event.subject(), !isNwAdminStateUp);
831 });
Jian Li91be8cd2018-07-22 00:44:46 +0900832 break;
833 case OPENSTACK_NETWORK_REMOVED:
Jian Li34220ea2018-11-14 01:30:24 +0900834 eventExecutor.execute(() -> {
835
836 if (!isRelevantHelper()) {
837 return;
838 }
839
840 setNetworkBlockRules(event.subject(), false);
841 });
Jian Li91be8cd2018-07-22 00:44:46 +0900842 break;
843 case OPENSTACK_PORT_CREATED:
844 case OPENSTACK_PORT_UPDATED:
Jian Li32b03622018-11-06 17:54:24 +0900845 eventExecutor.execute(() -> {
Jian Li34220ea2018-11-14 01:30:24 +0900846
847 if (!isRelevantHelper()) {
848 return;
849 }
850
Jian Li32b03622018-11-06 17:54:24 +0900851 InstancePort instPort = instancePortService.instancePort(portId);
852 if (instPort != null) {
853 setPortBlockRules(instPort, !isPortAdminStateUp);
854 }
855 });
Jian Li91be8cd2018-07-22 00:44:46 +0900856 break;
857 case OPENSTACK_PORT_REMOVED:
Jian Li32b03622018-11-06 17:54:24 +0900858 eventExecutor.execute(() -> {
Jian Li34220ea2018-11-14 01:30:24 +0900859
860 if (!isRelevantHelper()) {
861 return;
862 }
863
Jian Li32b03622018-11-06 17:54:24 +0900864 InstancePort instPort = instancePortService.instancePort(portId);
865 if (instPort != null) {
866 setPortBlockRules(instPort, false);
867 }
868 });
Jian Li91be8cd2018-07-22 00:44:46 +0900869 break;
870 default:
871 break;
872 }
873 }
874 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900875}