blob: e27b14a30df621308681cbb5f46cdfb43b84b46e [file] [log] [blame]
Hyunsun Moon44aac662017-02-18 02:07:01 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002* Copyright 2016-present Open Networking Foundation
Hyunsun Moon44aac662017-02-18 02:07:01 +09003*
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*/
16
17package org.onosproject.openstacknetworking.impl;
18
19import com.google.common.base.Strings;
20import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.onlab.packet.Ethernet;
Frank Wangf9571662017-06-06 18:01:29 +080026import org.onlab.packet.MacAddress;
daniel parka792cf72017-04-14 16:25:35 +090027import org.onlab.packet.VlanId;
Hyunsun Moon44aac662017-02-18 02:07:01 +090028import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
30import org.onosproject.mastership.MastershipService;
31import 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;
sangho1aaa7882017-05-31 13:22:47 +090037import org.onosproject.net.flow.instructions.ExtensionTreatment;
Hyunsun Moon44aac662017-02-18 02:07:01 +090038import org.onosproject.openstacknetworking.api.InstancePort;
39import org.onosproject.openstacknetworking.api.InstancePortEvent;
40import org.onosproject.openstacknetworking.api.InstancePortListener;
41import org.onosproject.openstacknetworking.api.InstancePortService;
sanghodc375372017-06-08 10:41:30 +090042import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090043import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
sanghoe6457a32017-08-24 14:31:19 +090044import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupService;
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;
Hyunsun Moon44aac662017-02-18 02:07:01 +090050import org.slf4j.Logger;
51
52import java.util.concurrent.ExecutorService;
53
54import static java.util.concurrent.Executors.newSingleThreadExecutor;
55import static org.onlab.util.Tools.groupedThreads;
sanghodc375372017-06-08 10:41:30 +090056import static org.onosproject.openstacknetworking.api.Constants.ACL_TABLE;
57import static org.onosproject.openstacknetworking.api.Constants.FORWARDING_TABLE;
58import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
Frank Wangf9571662017-06-06 18:01:29 +080059import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ADMIN_RULE;
sanghodc375372017-06-08 10:41:30 +090060import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
61import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_TUNNEL_TAG_RULE;
62import static org.onosproject.openstacknetworking.api.Constants.SRC_VNI_TABLE;
Hyunsun Moon44aac662017-02-18 02:07:01 +090063import static org.onosproject.openstacknetworking.impl.RulePopulatorUtil.buildExtension;
Hyunsun Moon0d457362017-06-27 17:19:41 +090064import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
Hyunsun Moon44aac662017-02-18 02:07:01 +090065import static org.slf4j.LoggerFactory.getLogger;
66
67
68/**
69 * Populates switching flow rules on OVS for the basic connectivity among the
70 * virtual instances in the same network.
71 */
72@Component(immediate = true)
73public final class OpenstackSwitchingHandler {
74
75 private final Logger log = getLogger(getClass());
76
Jian Li71670d12018-03-02 21:31:07 +090077 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 +090078
79 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +090080 protected CoreService coreService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090081
82 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +090083 protected MastershipService mastershipService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090084
85 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +090086 protected DeviceService deviceService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090087
88 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +090089 protected OpenstackFlowRuleService osFlowRuleService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090090
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +090092 protected InstancePortService instancePortService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090093
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +090095 protected OpenstackNetworkService osNetworkService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090096
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +090098 protected OpenstackNodeService osNodeService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090099
sangho1aaa7882017-05-31 13:22:47 +0900100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +0900101 protected DriverService driverService;
sangho1aaa7882017-05-31 13:22:47 +0900102
sanghoe6457a32017-08-24 14:31:19 +0900103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Liea1b9662018-03-02 18:07:32 +0900104 protected OpenstackSecurityGroupService securityGroupService;
sanghoe6457a32017-08-24 14:31:19 +0900105
Hyunsun Moon44aac662017-02-18 02:07:01 +0900106 private final ExecutorService eventExecutor = newSingleThreadExecutor(
107 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
108 private final InstancePortListener instancePortListener = new InternalInstancePortListener();
109 private ApplicationId appId;
110
111 @Activate
Ray Milkey9c9cde42018-01-12 14:22:06 -0800112 void activate() {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900113 appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
114 instancePortService.addListener(instancePortListener);
115
116 log.info("Started");
117 }
118
119 @Deactivate
Ray Milkey9c9cde42018-01-12 14:22:06 -0800120 void deactivate() {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900121 instancePortService.removeListener(instancePortListener);
122 eventExecutor.shutdown();
123
124 log.info("Stopped");
125 }
126
Jian Liea1b9662018-03-02 18:07:32 +0900127 /**
128 * Configures L2 forwarding rules.
129 * Currently, SONA only supports VXLAN and VLAN tunnelled L2 forwarding.
130 *
131 * @param instPort instance port object
132 * @param install install flag, add the rule if true, remove it otherwise
133 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900134 private void setNetworkRules(InstancePort instPort, boolean install) {
Jian Liea1b9662018-03-02 18:07:32 +0900135 NetworkType type = osNetworkService.network(instPort.networkId()).getNetworkType();
136 switch (type) {
daniel parka792cf72017-04-14 16:25:35 +0900137 case VXLAN:
138 setTunnelTagFlowRules(instPort, install);
139 setForwardingRules(instPort, install);
140 break;
141 case VLAN:
142 setVlanTagFlowRules(instPort, install);
143 setForwardingRulesForVlan(instPort, install);
144 break;
145 default:
Jian Liea1b9662018-03-02 18:07:32 +0900146 log.warn("Unsupported network tunnel type {}", type.name());
daniel parka792cf72017-04-14 16:25:35 +0900147 break;
148 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900149 }
150
Jian Liea1b9662018-03-02 18:07:32 +0900151 /**
152 * Configures the flow rules which are used for L2 packet switching.
153 * Note that these rules will be inserted in switching table (table 5).
154 *
155 * @param instPort instance port object
156 * @param install install flag, add the rule if true, remove it otherwise
157 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900158 private void setForwardingRules(InstancePort instPort, boolean install) {
159 // switching rules for the instPorts in the same node
160 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900161 // TODO: need to handle IPv6 in near future
Hyunsun Moon44aac662017-02-18 02:07:01 +0900162 .matchEthType(Ethernet.TYPE_IPV4)
163 .matchIPDst(instPort.ipAddress().toIpPrefix())
164 .matchTunnelId(getVni(instPort))
165 .build();
166
167 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900168 // TODO: this might not be necessary for the VMs located in the same subnet
Hyunsun Moon44aac662017-02-18 02:07:01 +0900169 .setEthDst(instPort.macAddress())
170 .setOutput(instPort.portNumber())
171 .build();
172
sanghodc375372017-06-08 10:41:30 +0900173 osFlowRuleService.setRule(
Hyunsun Moon44aac662017-02-18 02:07:01 +0900174 appId,
175 instPort.deviceId(),
176 selector,
177 treatment,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900178 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900179 FORWARDING_TABLE,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900180 install);
181
182 // switching rules for the instPorts in the remote node
Hyunsun Moon0d457362017-06-27 17:19:41 +0900183 OpenstackNode localNode = osNodeService.node(instPort.deviceId());
184 if (localNode == null) {
185 final String error = String.format("Cannot find openstack node for %s",
186 instPort.deviceId());
187 throw new IllegalStateException(error);
188 }
189 osNodeService.completeNodes(COMPUTE).stream()
190 .filter(remoteNode -> !remoteNode.intgBridge().equals(localNode.intgBridge()))
191 .forEach(remoteNode -> {
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900192 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
193 .extension(buildExtension(
194 deviceService,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900195 remoteNode.intgBridge(),
196 localNode.dataIp().getIp4Address()),
197 remoteNode.intgBridge())
198 .setOutput(remoteNode.tunnelPortNum())
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900199 .build();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900200
sanghodc375372017-06-08 10:41:30 +0900201 osFlowRuleService.setRule(
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900202 appId,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900203 remoteNode.intgBridge(),
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900204 selector,
205 treatmentToRemote,
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900206 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900207 FORWARDING_TABLE,
Hyunsun Moonacde3f52017-02-23 17:57:35 +0900208 install);
209 });
Hyunsun Moon44aac662017-02-18 02:07:01 +0900210 }
211
Jian Liea1b9662018-03-02 18:07:32 +0900212 /**
213 * Configures the flow rules which are used for L2 VLAN packet switching.
214 * Note that these rules will be inserted in switching table (table 5).
215 *
216 * @param instPort instance port object
217 * @param install install flag, add the rule if true, remove it otherwise
218 */
daniel parka792cf72017-04-14 16:25:35 +0900219 private void setForwardingRulesForVlan(InstancePort instPort, boolean install) {
220 // switching rules for the instPorts in the same node
221 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900222 // TODO: need to handle IPv6 in near future
daniel parka792cf72017-04-14 16:25:35 +0900223 .matchEthType(Ethernet.TYPE_IPV4)
224 .matchIPDst(instPort.ipAddress().toIpPrefix())
225 .matchVlanId(getVlanId(instPort))
226 .build();
227
228 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
229 .popVlan()
Jian Liea1b9662018-03-02 18:07:32 +0900230 // TODO: this might not be necessary for the VMs located in the same subnet
daniel parka792cf72017-04-14 16:25:35 +0900231 .setEthDst(instPort.macAddress())
232 .setOutput(instPort.portNumber())
233 .build();
234
sanghodc375372017-06-08 10:41:30 +0900235 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900236 appId,
237 instPort.deviceId(),
238 selector,
239 treatment,
daniel parka792cf72017-04-14 16:25:35 +0900240 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900241 FORWARDING_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900242 install);
243
244 // switching rules for the instPorts in the remote node
Hyunsun Moon0d457362017-06-27 17:19:41 +0900245 osNodeService.completeNodes(COMPUTE).stream()
246 .filter(remoteNode -> !remoteNode.intgBridge().equals(instPort.deviceId()) &&
247 remoteNode.vlanIntf() != null)
248 .forEach(remoteNode -> {
daniel parka792cf72017-04-14 16:25:35 +0900249 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
Hyunsun Moon0d457362017-06-27 17:19:41 +0900250 .setOutput(remoteNode.vlanPortNum())
daniel parka792cf72017-04-14 16:25:35 +0900251 .build();
252
sanghodc375372017-06-08 10:41:30 +0900253 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900254 appId,
Hyunsun Moon0d457362017-06-27 17:19:41 +0900255 remoteNode.intgBridge(),
daniel parka792cf72017-04-14 16:25:35 +0900256 selector,
257 treatmentToRemote,
daniel parka792cf72017-04-14 16:25:35 +0900258 PRIORITY_SWITCHING_RULE,
sanghodc375372017-06-08 10:41:30 +0900259 FORWARDING_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900260 install);
261 });
daniel parka792cf72017-04-14 16:25:35 +0900262 }
263
Jian Liea1b9662018-03-02 18:07:32 +0900264 /**
265 * Configures the flow rule which is for using VXLAN to tag the packet
266 * based on the in_port number of a virtual instance.
267 * Note that this rule will be inserted in VNI table (table 0).
268 *
269 * @param instPort instance port object
270 * @param install install flag, add the rule if true, remove it otherwise
271 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900272 private void setTunnelTagFlowRules(InstancePort instPort, boolean install) {
273 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900274 // TODO: need to handle IPv6 in near future
Hyunsun Moon44aac662017-02-18 02:07:01 +0900275 .matchEthType(Ethernet.TYPE_IPV4)
276 .matchInPort(instPort.portNumber())
277 .build();
278
Jian Liea1b9662018-03-02 18:07:32 +0900279 // XXX All egress traffic needs to go through connection tracking module,
280 // which might hurt its performance.
sangho1aaa7882017-05-31 13:22:47 +0900281 ExtensionTreatment ctTreatment =
282 RulePopulatorUtil.niciraConnTrackTreatmentBuilder(driverService, instPort.deviceId())
283 .commit(true).build();
284
sanghoe6457a32017-08-24 14:31:19 +0900285 TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder()
Hyunsun Moon44aac662017-02-18 02:07:01 +0900286 .setTunnelId(getVni(instPort))
sanghoe6457a32017-08-24 14:31:19 +0900287 .transition(ACL_TABLE);
288
289 if (securityGroupService.isSecurityGroupEnabled()) {
290 tb.extension(ctTreatment, instPort.deviceId());
291 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900292
sanghodc375372017-06-08 10:41:30 +0900293 osFlowRuleService.setRule(
Hyunsun Moon44aac662017-02-18 02:07:01 +0900294 appId,
295 instPort.deviceId(),
296 selector,
sanghoe6457a32017-08-24 14:31:19 +0900297 tb.build(),
Hyunsun Moon44aac662017-02-18 02:07:01 +0900298 PRIORITY_TUNNEL_TAG_RULE,
sanghodc375372017-06-08 10:41:30 +0900299 SRC_VNI_TABLE,
Hyunsun Moon44aac662017-02-18 02:07:01 +0900300 install);
301 }
302
Jian Liea1b9662018-03-02 18:07:32 +0900303 /**
304 * Configures the flow rule which is for using VLAN to tag the packet
305 * based on the in_port number of a virtual instance.
306 * Note that this rule will be inserted in VNI table (table 0).
307 *
308 * @param instPort instance port object
309 * @param install install flag, add the rule if true, remove it otherwise
310 */
daniel parka792cf72017-04-14 16:25:35 +0900311 private void setVlanTagFlowRules(InstancePort instPort, boolean install) {
312 TrafficSelector selector = DefaultTrafficSelector.builder()
Jian Liea1b9662018-03-02 18:07:32 +0900313 // TODO: need to handle IPv6 in near future
daniel parka792cf72017-04-14 16:25:35 +0900314 .matchEthType(Ethernet.TYPE_IPV4)
315 .matchInPort(instPort.portNumber())
316 .build();
317
318 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
319 .pushVlan()
320 .setVlanId(getVlanId(instPort))
sanghodc375372017-06-08 10:41:30 +0900321 .transition(ACL_TABLE)
daniel parka792cf72017-04-14 16:25:35 +0900322 .build();
323
sanghodc375372017-06-08 10:41:30 +0900324 osFlowRuleService.setRule(
daniel parka792cf72017-04-14 16:25:35 +0900325 appId,
326 instPort.deviceId(),
327 selector,
328 treatment,
daniel parka792cf72017-04-14 16:25:35 +0900329 PRIORITY_TUNNEL_TAG_RULE,
sanghodc375372017-06-08 10:41:30 +0900330 SRC_VNI_TABLE,
daniel parka792cf72017-04-14 16:25:35 +0900331 install);
daniel parka792cf72017-04-14 16:25:35 +0900332 }
333
Frank Wangf9571662017-06-06 18:01:29 +0800334 private void setNetworkAdminRules(Network network, boolean install) {
335 TrafficSelector selector;
336 if (network.getNetworkType() == NetworkType.VXLAN) {
337
338 selector = DefaultTrafficSelector.builder()
339 .matchTunnelId(Long.valueOf(network.getProviderSegID()))
340 .build();
341 } else {
342 selector = DefaultTrafficSelector.builder()
343 .matchVlanId(VlanId.vlanId(network.getProviderSegID()))
344 .build();
345 }
346
347 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
348 .drop()
349 .build();
350
351 osNodeService.completeNodes().stream()
352 .filter(osNode -> osNode.type() == COMPUTE)
Jian Liea1b9662018-03-02 18:07:32 +0900353 .forEach(osNode ->
Frank Wangf9571662017-06-06 18:01:29 +0800354 osFlowRuleService.setRule(
355 appId,
356 osNode.intgBridge(),
357 selector,
358 treatment,
359 PRIORITY_ADMIN_RULE,
360 ACL_TABLE,
Jian Liea1b9662018-03-02 18:07:32 +0900361 install)
362 );
Frank Wangf9571662017-06-06 18:01:29 +0800363 }
364
365 private void setPortAdminRules(Port port, boolean install) {
Jian Liea1b9662018-03-02 18:07:32 +0900366 InstancePort instancePort =
367 instancePortService.instancePort(MacAddress.valueOf(port.getMacAddress()));
Frank Wangf9571662017-06-06 18:01:29 +0800368 TrafficSelector selector = DefaultTrafficSelector.builder()
369 .matchInPort(instancePort.portNumber())
370 .build();
371
372 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
373 .drop()
374 .build();
375
376 osFlowRuleService.setRule(
377 appId,
378 instancePort.deviceId(),
379 selector,
380 treatment,
381 PRIORITY_ADMIN_RULE,
382 SRC_VNI_TABLE,
383 install);
384 }
385
Jian Liea1b9662018-03-02 18:07:32 +0900386 /**
387 * Obtains the VLAN ID from the given instance port.
388 *
389 * @param instPort instance port object
390 * @return VLAN ID
391 */
daniel parka792cf72017-04-14 16:25:35 +0900392 private VlanId getVlanId(InstancePort instPort) {
393 Network osNet = osNetworkService.network(instPort.networkId());
394
395 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900396 final String error =
397 String.format(ERR_SET_FLOWS_VNI,
398 instPort, osNet == null ? "<none>" : osNet.getName());
daniel parka792cf72017-04-14 16:25:35 +0900399 throw new IllegalStateException(error);
400 }
401
402 return VlanId.vlanId(osNet.getProviderSegID());
403 }
404
Jian Liea1b9662018-03-02 18:07:32 +0900405 /**
406 * Obtains the VNI from the given instance port.
407 *
408 * @param instPort instance port object
409 * @return VXLAN Network Identifier (VNI)
410 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900411 private Long getVni(InstancePort instPort) {
412 Network osNet = osNetworkService.network(instPort.networkId());
413 if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
Jian Li71670d12018-03-02 21:31:07 +0900414 final String error =
415 String.format(ERR_SET_FLOWS_VNI,
416 instPort, osNet == null ? "<none>" : osNet.getName());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900417 throw new IllegalStateException(error);
418 }
419 return Long.valueOf(osNet.getProviderSegID());
420 }
421
Jian Liea1b9662018-03-02 18:07:32 +0900422 /**
423 * An internal instance port listener which listens the port events generated
424 * from VM. The corresponding L2 forwarding rules will be generated and
425 * inserted to integration bridge only if a new VM port is detected. If the
426 * existing detected VM port is removed due to VM purge, we will remove the
427 * corresponding L2 forwarding to as well for the sake of resource saving.
428 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900429 private class InternalInstancePortListener implements InstancePortListener {
430
431 @Override
432 public boolean isRelevant(InstancePortEvent event) {
433 InstancePort instPort = event.subject();
434 return mastershipService.isLocalMaster(instPort.deviceId());
435 }
436
437 @Override
438 public void event(InstancePortEvent event) {
439 InstancePort instPort = event.subject();
440 switch (event.type()) {
441 case OPENSTACK_INSTANCE_PORT_UPDATED:
442 case OPENSTACK_INSTANCE_PORT_DETECTED:
443 eventExecutor.execute(() -> {
444 log.info("Instance port detected MAC:{} IP:{}",
445 instPort.macAddress(),
446 instPort.ipAddress());
447 instPortDetected(event.subject());
448 });
449 break;
450 case OPENSTACK_INSTANCE_PORT_VANISHED:
451 eventExecutor.execute(() -> {
452 log.info("Instance port vanished MAC:{} IP:{}",
453 instPort.macAddress(),
454 instPort.ipAddress());
455 instPortRemoved(event.subject());
456 });
457 break;
458 default:
459 break;
460 }
461 }
462
463 private void instPortDetected(InstancePort instPort) {
464 setNetworkRules(instPort, true);
465 // TODO add something else if needed
466 }
467
468 private void instPortRemoved(InstancePort instPort) {
469 setNetworkRules(instPort, false);
470 // TODO add something else if needed
471 }
472 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900473}