blob: 9bd06efdffeac69b0505f1a0fea62faaeaab2c71 [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)
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) {
Jian Li1e9cb732018-11-25 23:17:21 +0900506 tBuilder.transition(ACL_EGRESS_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
Daniel Park8a9220f2018-11-19 18:58:35 +0900543 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
daniel parka792cf72017-04-14 16:25:35 +0900544 .pushVlan()
Daniel Park8a9220f2018-11-19 18:58:35 +0900545 .setVlanId(getVlanId(instPort));
546
547 if (ethType == Ethernet.TYPE_ARP) {
548 tBuilder.transition(ARP_TABLE);
549 } else if (ethType == Ethernet.TYPE_IPV4) {
Jian Li1e9cb732018-11-25 23:17:21 +0900550 tBuilder.transition(ACL_EGRESS_TABLE);
Daniel Park8a9220f2018-11-19 18:58:35 +0900551 }
daniel parka792cf72017-04-14 16:25:35 +0900552
sanghodc375372017-06-08 10:41:30 +0900553 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900554 appId,
555 instPort.deviceId(),
556 selector,
Daniel Park8a9220f2018-11-19 18:58:35 +0900557 tBuilder.build(),
daniel parka792cf72017-04-14 16:25:35 +0900558 PRIORITY_TUNNEL_TAG_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900559 VTAG_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900560 install);
daniel parka792cf72017-04-14 16:25:35 +0900561 }
562
Jian Li91be8cd2018-07-22 00:44:46 +0900563 private void setNetworkBlockRules(Network network, boolean install) {
Frank Wangf9571662017-06-06 18:01:29 +0800564
Jian Li91be8cd2018-07-22 00:44:46 +0900565 NetworkType type = network.getNetworkType();
566
567 // TODO: we block a network traffic by referring to segment ID for now
568 // we might need to find a better way to block the traffic of a network
569 // in case the segment ID is overlapped in different types network (VXLAN, VLAN)
570 switch (type) {
571 case VXLAN:
572 setNetworkBlockRulesForVxlan(network.getProviderSegID(), install);
573 break;
574 case VLAN:
575 setNetworkBlockRulesForVlan(network.getProviderSegID(), install);
576 break;
577 case FLAT:
578 // TODO: need to find a way to block flat typed network
579 break;
580 default:
581 break;
Frank Wangf9571662017-06-06 18:01:29 +0800582 }
Jian Li91be8cd2018-07-22 00:44:46 +0900583 }
584
585 private void setNetworkBlockRulesForVxlan(String segmentId, boolean install) {
586 TrafficSelector selector = DefaultTrafficSelector.builder()
587 .matchTunnelId(Long.valueOf(segmentId))
588 .build();
Frank Wangf9571662017-06-06 18:01:29 +0800589
590 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
591 .drop()
592 .build();
593
Jian Li91be8cd2018-07-22 00:44:46 +0900594 osNodeService.completeNodes(COMPUTE)
Jian Liea1b9662018-03-02 18:07:32 +0900595 .forEach(osNode ->
Frank Wangf9571662017-06-06 18:01:29 +0800596 osFlowRuleService.setRule(
Jian Li91be8cd2018-07-22 00:44:46 +0900597 appId,
598 osNode.intgBridge(),
599 selector,
600 treatment,
601 PRIORITY_ADMIN_RULE,
Jian Li1e9cb732018-11-25 23:17:21 +0900602 ACL_EGRESS_TABLE,
Jian Li91be8cd2018-07-22 00:44:46 +0900603 install)
Jian Liea1b9662018-03-02 18:07:32 +0900604 );
Frank Wangf9571662017-06-06 18:01:29 +0800605 }
606
Jian Li91be8cd2018-07-22 00:44:46 +0900607 private void setNetworkBlockRulesForVlan(String segmentId, boolean install) {
Frank Wangf9571662017-06-06 18:01:29 +0800608 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Li91be8cd2018-07-22 00:44:46 +0900609 .matchTunnelId(Long.valueOf(segmentId))
610 .build();
611
612 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
613 .drop()
614 .build();
615
616 osNodeService.completeNodes(COMPUTE)
617 .forEach(osNode ->
618 osFlowRuleService.setRule(
619 appId,
620 osNode.intgBridge(),
621 selector,
622 treatment,
623 PRIORITY_ADMIN_RULE,
Jian Li1e9cb732018-11-25 23:17:21 +0900624 ACL_EGRESS_TABLE,
Jian Li91be8cd2018-07-22 00:44:46 +0900625 install)
626 );
627 }
628
629 private void setPortBlockRules(InstancePort instPort, boolean install) {
630 TrafficSelector selector = DefaultTrafficSelector.builder()
631 .matchInPort(instPort.portNumber())
Frank Wangf9571662017-06-06 18:01:29 +0800632 .build();
633
634 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
635 .drop()
636 .build();
637
638 osFlowRuleService.setRule(
639 appId,
Jian Li91be8cd2018-07-22 00:44:46 +0900640 instPort.deviceId(),
Frank Wangf9571662017-06-06 18:01:29 +0800641 selector,
642 treatment,
643 PRIORITY_ADMIN_RULE,
Jian Li70a2c3f2018-04-13 17:26:31 +0900644 VTAG_TABLE,
Frank Wangf9571662017-06-06 18:01:29 +0800645 install);
646 }
647
Jian Liea1b9662018-03-02 18:07:32 +0900648 /**
649 * Obtains the VLAN ID from the given instance port.
650 *
651 * @param instPort instance port object
652 * @return VLAN ID
653 */
daniel parka792cf72017-04-14 16:25:35 +0900654 private VlanId getVlanId(InstancePort instPort) {
655 Network osNet = osNetworkService.network(instPort.networkId());
656
657 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900658 final String error =
659 String.format(ERR_SET_FLOWS_VNI,
660 instPort, osNet == null ? "<none>" : osNet.getName());
daniel parka792cf72017-04-14 16:25:35 +0900661 throw new IllegalStateException(error);
662 }
663
664 return VlanId.vlanId(osNet.getProviderSegID());
665 }
666
Jian Liea1b9662018-03-02 18:07:32 +0900667 /**
668 * Obtains the VNI from the given instance port.
669 *
670 * @param instPort instance port object
671 * @return VXLAN Network Identifier (VNI)
672 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900673 private Long getVni(InstancePort instPort) {
674 Network osNet = osNetworkService.network(instPort.networkId());
675 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900676 final String error =
677 String.format(ERR_SET_FLOWS_VNI,
678 instPort, osNet == null ? "<none>" : osNet.getName());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900679 throw new IllegalStateException(error);
680 }
681 return Long.valueOf(osNet.getProviderSegID());
682 }
683
Jian Li5c09e212018-10-24 18:23:58 +0900684 private String getArpMode() {
Jian Li34220ea2018-11-14 01:30:24 +0900685 Set<ConfigProperty> properties =
686 configService.getProperties(OpenstackSwitchingArpHandler.class.getName());
Jian Li5c09e212018-10-24 18:23:58 +0900687 return getPropertyValue(properties, ARP_MODE);
688 }
689
Jian Liea1b9662018-03-02 18:07:32 +0900690 /**
691 * An internal instance port listener which listens the port events generated
692 * from VM. The corresponding L2 forwarding rules will be generated and
693 * inserted to integration bridge only if a new VM port is detected. If the
694 * existing detected VM port is removed due to VM purge, we will remove the
695 * corresponding L2 forwarding to as well for the sake of resource saving.
696 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900697 private class InternalInstancePortListener implements InstancePortListener {
698
Jian Li34220ea2018-11-14 01:30:24 +0900699 private boolean isRelevantHelper(InstancePortEvent event) {
700 return mastershipService.isLocalMaster(event.subject().deviceId());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900701 }
702
703 @Override
704 public void event(InstancePortEvent event) {
705 InstancePort instPort = event.subject();
Jian Li9a921b42018-06-18 02:44:50 +0900706
Hyunsun Moon44aac662017-02-18 02:07:01 +0900707 switch (event.type()) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900708 case OPENSTACK_INSTANCE_PORT_DETECTED:
Jian Liec5c32b2018-07-13 14:28:58 +0900709 case OPENSTACK_INSTANCE_PORT_UPDATED:
Jian Li34220ea2018-11-14 01:30:24 +0900710 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
Jian Li46b74002018-07-15 18:39:08 +0900711 case OPENSTACK_INSTANCE_RESTARTED:
Jian Li34220ea2018-11-14 01:30:24 +0900712
713 if (event.type() == OPENSTACK_INSTANCE_MIGRATION_STARTED) {
714 log.info("SwitchingHandler: Migration started at MAC:{} IP:{}",
Jian Li9a921b42018-06-18 02:44:50 +0900715 instPort.macAddress(),
716 instPort.ipAddress());
Jian Li34220ea2018-11-14 01:30:24 +0900717 } else {
718 log.info("SwitchingHandler: Instance port detected MAC:{} IP:{}",
719 instPort.macAddress(),
720 instPort.ipAddress());
Jian Li91be8cd2018-07-22 00:44:46 +0900721 }
722
Jian Li34220ea2018-11-14 01:30:24 +0900723 eventExecutor.execute(() -> {
724
725 if (!isRelevantHelper(event)) {
726 return;
727 }
728
729 instPortDetected(instPort);
730
731 Port osPort = osNetworkService.port(instPort.portId());
732
733 if (osPort != null) {
734 setPortBlockRules(instPort, !osPort.isAdminStateUp());
735 }
736 });
737
Hyunsun Moon44aac662017-02-18 02:07:01 +0900738 break;
Jian Li46b74002018-07-15 18:39:08 +0900739 case OPENSTACK_INSTANCE_TERMINATED:
740 log.info("SwitchingHandler: Instance port terminated MAC:{} IP:{}",
741 instPort.macAddress(),
742 instPort.ipAddress());
Jian Li34220ea2018-11-14 01:30:24 +0900743 eventExecutor.execute(() -> {
744
745 if (!isRelevantHelper(event)) {
746 return;
747 }
748
749 removeVportRules(instPort);
750 });
Jian Li46b74002018-07-15 18:39:08 +0900751
752 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900753 case OPENSTACK_INSTANCE_PORT_VANISHED:
Jian Liec5c32b2018-07-13 14:28:58 +0900754 log.info("SwitchingHandler: Instance port vanished MAC:{} IP:{}",
Jian Li9a921b42018-06-18 02:44:50 +0900755 instPort.macAddress(),
756 instPort.ipAddress());
Jian Liec5c32b2018-07-13 14:28:58 +0900757
Jian Li34220ea2018-11-14 01:30:24 +0900758 eventExecutor.execute(() -> {
Jian Li9a921b42018-06-18 02:44:50 +0900759
Jian Li34220ea2018-11-14 01:30:24 +0900760 if (!isRelevantHelper(event)) {
761 return;
762 }
Jian Li91be8cd2018-07-22 00:44:46 +0900763
Jian Li34220ea2018-11-14 01:30:24 +0900764 instPortRemoved(instPort);
Jian Liec5c32b2018-07-13 14:28:58 +0900765
Jian Li34220ea2018-11-14 01:30:24 +0900766 Port osPort = osNetworkService.port(instPort.portId());
Jian Liec5c32b2018-07-13 14:28:58 +0900767
Jian Li34220ea2018-11-14 01:30:24 +0900768 if (osPort != null) {
769 setPortBlockRules(instPort, false);
770 }
771 });
Jian Li91be8cd2018-07-22 00:44:46 +0900772
Jian Liec5c32b2018-07-13 14:28:58 +0900773 break;
774 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
775 log.info("SwitchingHandler: Migration finished for MAC:{} IP:{}",
776 instPort.macAddress(),
777 instPort.ipAddress());
778
779 InstancePort revisedInstPort = swapStaleLocation(instPort);
Jian Li34220ea2018-11-14 01:30:24 +0900780 eventExecutor.execute(() -> {
781
782 if (!isRelevantHelper(event)) {
783 return;
784 }
785
786 removeVportRules(revisedInstPort);
787 });
Jian Liec5c32b2018-07-13 14:28:58 +0900788
Jian Li24ec59f2018-05-23 19:01:25 +0900789 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900790 default:
791 break;
792 }
793 }
794
795 private void instPortDetected(InstancePort instPort) {
796 setNetworkRules(instPort, true);
797 // TODO add something else if needed
798 }
799
800 private void instPortRemoved(InstancePort instPort) {
801 setNetworkRules(instPort, false);
802 // TODO add something else if needed
803 }
804 }
Jian Li91be8cd2018-07-22 00:44:46 +0900805
806 private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
807
808 @Override
809 public boolean isRelevant(OpenstackNetworkEvent event) {
Jian Li34220ea2018-11-14 01:30:24 +0900810 return event.subject() != null && event.port() != null;
811 }
Jian Li91be8cd2018-07-22 00:44:46 +0900812
Jian Li34220ea2018-11-14 01:30:24 +0900813 private boolean isRelevantHelper() {
814 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
Jian Li91be8cd2018-07-22 00:44:46 +0900815 }
816
817 @Override
818 public void event(OpenstackNetworkEvent event) {
819
Jian Li91be8cd2018-07-22 00:44:46 +0900820 boolean isNwAdminStateUp = event.subject().isAdminStateUp();
821 boolean isPortAdminStateUp = event.port().isAdminStateUp();
822
Jian Li32b03622018-11-06 17:54:24 +0900823 String portId = event.port().getId();
Jian Li91be8cd2018-07-22 00:44:46 +0900824
825 switch (event.type()) {
826 case OPENSTACK_NETWORK_CREATED:
827 case OPENSTACK_NETWORK_UPDATED:
Jian Li34220ea2018-11-14 01:30:24 +0900828 eventExecutor.execute(() -> {
Jian Li91be8cd2018-07-22 00:44:46 +0900829
Jian Li34220ea2018-11-14 01:30:24 +0900830 if (!isRelevantHelper()) {
831 return;
832 }
833
834 setNetworkBlockRules(event.subject(), !isNwAdminStateUp);
835 });
Jian Li91be8cd2018-07-22 00:44:46 +0900836 break;
837 case OPENSTACK_NETWORK_REMOVED:
Jian Li34220ea2018-11-14 01:30:24 +0900838 eventExecutor.execute(() -> {
839
840 if (!isRelevantHelper()) {
841 return;
842 }
843
844 setNetworkBlockRules(event.subject(), false);
845 });
Jian Li91be8cd2018-07-22 00:44:46 +0900846 break;
847 case OPENSTACK_PORT_CREATED:
848 case OPENSTACK_PORT_UPDATED:
Jian Li32b03622018-11-06 17:54:24 +0900849 eventExecutor.execute(() -> {
Jian Li34220ea2018-11-14 01:30:24 +0900850
851 if (!isRelevantHelper()) {
852 return;
853 }
854
Jian Li32b03622018-11-06 17:54:24 +0900855 InstancePort instPort = instancePortService.instancePort(portId);
856 if (instPort != null) {
857 setPortBlockRules(instPort, !isPortAdminStateUp);
858 }
859 });
Jian Li91be8cd2018-07-22 00:44:46 +0900860 break;
861 case OPENSTACK_PORT_REMOVED:
Jian Li32b03622018-11-06 17:54:24 +0900862 eventExecutor.execute(() -> {
Jian Li34220ea2018-11-14 01:30:24 +0900863
864 if (!isRelevantHelper()) {
865 return;
866 }
867
Jian Li32b03622018-11-06 17:54:24 +0900868 InstancePort instPort = instancePortService.instancePort(portId);
869 if (instPort != null) {
870 setPortBlockRules(instPort, false);
871 }
872 });
Jian Li91be8cd2018-07-22 00:44:46 +0900873 break;
874 default:
875 break;
876 }
877 }
878 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900879}