blob: 5c7bd5e119232d1065970285b0e90256cca6efbf [file] [log] [blame]
sanghoshin94872a12015-10-16 18:04:34 +09001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002* Copyright 2016-present Open Networking Laboratory
sanghoshin94872a12015-10-16 18:04:34 +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
sangho0c2a3da2016-02-16 13:39:07 +090017package org.onosproject.openstacknetworking.switching;
sanghoshin94872a12015-10-16 18:04:34 +090018
19import org.onlab.packet.Ethernet;
sanghoshin94872a12015-10-16 18:04:34 +090020import org.onlab.packet.Ip4Address;
sanghoshin94872a12015-10-16 18:04:34 +090021import org.onosproject.core.ApplicationId;
sanghoshinf25d2e02015-11-11 23:07:17 +090022import org.onosproject.net.Device;
sanghoshin94872a12015-10-16 18:04:34 +090023import org.onosproject.net.DeviceId;
24import org.onosproject.net.Port;
25import org.onosproject.net.PortNumber;
sanghoshinf25d2e02015-11-11 23:07:17 +090026import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
27import org.onosproject.net.device.DeviceService;
28import org.onosproject.net.driver.DefaultDriverData;
29import org.onosproject.net.driver.DefaultDriverHandler;
30import org.onosproject.net.driver.Driver;
31import org.onosproject.net.driver.DriverHandler;
32import org.onosproject.net.driver.DriverService;
sanghoshin94872a12015-10-16 18:04:34 +090033import org.onosproject.net.flow.DefaultTrafficSelector;
34import org.onosproject.net.flow.DefaultTrafficTreatment;
35import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
sanghoshinf25d2e02015-11-11 23:07:17 +090037import org.onosproject.net.flow.instructions.ExtensionTreatment;
38import org.onosproject.net.flow.instructions.ExtensionPropertyException;
39import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
sanghoshin94872a12015-10-16 18:04:34 +090040import org.onosproject.net.flowobjective.DefaultForwardingObjective;
41import org.onosproject.net.flowobjective.FlowObjectiveService;
42import org.onosproject.net.flowobjective.ForwardingObjective;
sangho93447f12016-02-24 00:33:22 +090043import org.onosproject.openstackinterface.OpenstackInterfaceService;
44import org.onosproject.openstackinterface.OpenstackNetwork;
45import org.onosproject.openstackinterface.OpenstackPort;
sangho0c2a3da2016-02-16 13:39:07 +090046import org.onosproject.openstacknetworking.OpenstackPortInfo;
sanghoshin94872a12015-10-16 18:04:34 +090047import org.slf4j.Logger;
48import org.slf4j.LoggerFactory;
49
sanghoshinf25d2e02015-11-11 23:07:17 +090050import java.util.Collection;
Daniel Park5df65182016-01-09 00:12:03 +090051import java.util.Map;
sanghoshinf25d2e02015-11-11 23:07:17 +090052
sanghoshin94872a12015-10-16 18:04:34 +090053/**
sanghoshin46297d22015-11-03 17:51:24 +090054 * Populates switching flow rules.
sanghoshin94872a12015-10-16 18:04:34 +090055 */
56public class OpenstackSwitchingRulePopulator {
57
58 private static Logger log = LoggerFactory
59 .getLogger(OpenstackSwitchingRulePopulator.class);
daniel2a2bd7b2015-12-02 13:53:58 +090060 private static final int SWITCHING_RULE_PRIORITY = 30000;
daniel2a2bd7b2015-12-02 13:53:58 +090061 private static final int TUNNELTAG_RULE_PRIORITY = 30000;
Daniel Park23193902016-03-24 18:17:19 +090062 private static final String PORT_NAME = "portName";
63 private static final String TUNNEL_DST = "tunnelDst";
sanghoshin94872a12015-10-16 18:04:34 +090064 private FlowObjectiveService flowObjectiveService;
sanghoshinf25d2e02015-11-11 23:07:17 +090065 private DriverService driverService;
66 private DeviceService deviceService;
sanghoshin94872a12015-10-16 18:04:34 +090067 private ApplicationId appId;
Daniel Park23193902016-03-24 18:17:19 +090068 private OpenstackSwitchingConfig config;
sanghoshin94872a12015-10-16 18:04:34 +090069
sanghoshinf25d2e02015-11-11 23:07:17 +090070 private Collection<OpenstackNetwork> openstackNetworkList;
71 private Collection<OpenstackPort> openstackPortList;
72
sanghoshin94872a12015-10-16 18:04:34 +090073 /**
Ray Milkey87b16b02015-10-30 11:50:00 -070074 * Creates OpenstackSwitchingRulPopulator.
75 *
76 * @param appId application id
sanghoshin94872a12015-10-16 18:04:34 +090077 * @param flowObjectiveService FlowObjectiveService reference
sanghoshinf25d2e02015-11-11 23:07:17 +090078 * @param deviceService DeviceService reference
Hyunsun Moon0dba61f2016-03-03 14:05:21 -080079 * @param openstackService openstack interface service
sanghoshinf25d2e02015-11-11 23:07:17 +090080 * @param driverService DriverService reference
Daniel Park23193902016-03-24 18:17:19 +090081 * @param config OpenstackRoutingConfig
sanghoshin94872a12015-10-16 18:04:34 +090082 */
83 public OpenstackSwitchingRulePopulator(ApplicationId appId,
sanghoshinf25d2e02015-11-11 23:07:17 +090084 FlowObjectiveService flowObjectiveService,
85 DeviceService deviceService,
sangho93447f12016-02-24 00:33:22 +090086 OpenstackInterfaceService openstackService,
Daniel Park23193902016-03-24 18:17:19 +090087 DriverService driverService,
88 OpenstackSwitchingConfig config) {
sanghoshin94872a12015-10-16 18:04:34 +090089 this.flowObjectiveService = flowObjectiveService;
sanghoshinf25d2e02015-11-11 23:07:17 +090090 this.deviceService = deviceService;
91 this.driverService = driverService;
sanghoshin94872a12015-10-16 18:04:34 +090092 this.appId = appId;
Daniel Park23193902016-03-24 18:17:19 +090093 this.config = config;
sanghoshinf25d2e02015-11-11 23:07:17 +090094
sangho0c2a3da2016-02-16 13:39:07 +090095 openstackNetworkList = openstackService.networks();
96 openstackPortList = openstackService.ports();
sanghoshin94872a12015-10-16 18:04:34 +090097 }
98
daniel2a2bd7b2015-12-02 13:53:58 +090099
sanghoshin94872a12015-10-16 18:04:34 +0900100 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900101 * Populates flow rules for the VM created.
sanghoshin94872a12015-10-16 18:04:34 +0900102 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900103 * @param device device to populate rules to
104 * @param port port for the VM created
sanghoshin94872a12015-10-16 18:04:34 +0900105 */
sangho93447f12016-02-24 00:33:22 +0900106 public void populateSwitchingRules(Device device, Port port) {
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800107 populateFlowRulesForTunnelTag(device, port);
sanghoshinf25d2e02015-11-11 23:07:17 +0900108 populateFlowRulesForTrafficToSameCnode(device, port);
109 populateFlowRulesForTrafficToDifferentCnode(device, port);
sanghoshin94872a12015-10-16 18:04:34 +0900110 }
111
112 /**
daniel2a2bd7b2015-12-02 13:53:58 +0900113 * Populate the flow rules for tagging tunnelId according to which inport is came from.
114 *
115 * @param device device to put the rules
116 * @param port port info of the VM
117 */
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800118 private void populateFlowRulesForTunnelTag(Device device, Port port) {
Daniel Park23193902016-03-24 18:17:19 +0900119 Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value(PORT_NAME));
120 String portName = port.annotations().value(PORT_NAME);
daniel2a2bd7b2015-12-02 13:53:58 +0900121 String vni = getVniForPort(portName);
122
123 if (vmIp != null) {
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800124 setFlowRuleForTunnelTag(device.id(), port, vni);
daniel2a2bd7b2015-12-02 13:53:58 +0900125 }
126 }
127
Daniel Park5df65182016-01-09 00:12:03 +0900128 private void setFlowRuleForTunnelTag(DeviceId deviceId, Port port, String vni) {
sanghoshin075e3e72015-11-25 16:34:29 +0900129
Daniel Park5df65182016-01-09 00:12:03 +0900130 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
131 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
132
133 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
134 .matchInPort(port.number());
135
136 tBuilder.setTunnelId(Long.parseLong(vni));
137
138 ForwardingObjective fo = DefaultForwardingObjective.builder()
139 .withSelector(sBuilder.build())
140 .withTreatment(tBuilder.build())
141 .withPriority(TUNNELTAG_RULE_PRIORITY)
142 .withFlag(ForwardingObjective.Flag.SPECIFIC)
143 .fromApp(appId)
144 .add();
145
146 flowObjectiveService.forward(deviceId, fo);
sanghoshin65723ae2015-11-17 22:07:21 +0900147 }
148
149 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900150 * Populates the flow rules for traffic to VMs in the same Cnode as the sender.
sanghoshin94872a12015-10-16 18:04:34 +0900151 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900152 * @param device device to put the rules
153 * @param port port info of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900154 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900155 private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) {
Daniel Park23193902016-03-24 18:17:19 +0900156 Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value(PORT_NAME));
157 String portName = port.annotations().value(PORT_NAME);
daniel2a2bd7b2015-12-02 13:53:58 +0900158 String vni = getVniForPort(portName);
daniel2a2bd7b2015-12-02 13:53:58 +0900159
sanghoshinf25d2e02015-11-11 23:07:17 +0900160 if (vmIp != null) {
Daniel Park5df65182016-01-09 00:12:03 +0900161 setFlowRuleForVMsInSameCnode(vmIp, device.id(), port, vni);
sanghoshinf25d2e02015-11-11 23:07:17 +0900162 }
sanghoshin94872a12015-10-16 18:04:34 +0900163 }
164
165 /**
Daniel Park5df65182016-01-09 00:12:03 +0900166 * Sets the flow rules for traffic between VMs in the same Cnode.
167 *
168 * @param ip4Address VM IP address
169 * @param id device ID to put rules
170 * @param port VM port
171 * @param vni VM VNI
172 */
173 private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id,
174 Port port, String vni) {
175
176 //For L2 Switching Case
177 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
178 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
179
180 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
181 .matchIPDst(ip4Address.toIpPrefix())
182 .matchTunnelId(Long.parseLong(vni));
183
184 tBuilder.setOutput(port.number());
185
186 ForwardingObjective fo = DefaultForwardingObjective.builder()
187 .withSelector(sBuilder.build())
188 .withTreatment(tBuilder.build())
189 .withPriority(SWITCHING_RULE_PRIORITY)
190 .withFlag(ForwardingObjective.Flag.SPECIFIC)
191 .fromApp(appId)
192 .add();
193
194 flowObjectiveService.forward(id, fo);
195 }
196
197 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900198 * Populates the flow rules for traffic to VMs in different Cnode using
199 * Nicira extention.
sanghoshin94872a12015-10-16 18:04:34 +0900200 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900201 * @param device device to put rules
202 * @param port port information of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900203 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900204 private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) {
Daniel Park23193902016-03-24 18:17:19 +0900205 String portName = port.annotations().value(PORT_NAME);
sanghoshinf25d2e02015-11-11 23:07:17 +0900206 Ip4Address fixedIp = getFixedIpAddressForPort(portName);
sanghoshinf25d2e02015-11-11 23:07:17 +0900207 String vni = getVniForPort(portName);
Daniel Park23193902016-03-24 18:17:19 +0900208 Ip4Address hostDpIpAddress = config.nodes().get(device.id());
209
210 if (hostDpIpAddress == null) {
211 log.debug("There's no openstack node information for device id {}", device.id().toString());
212 return;
213 }
214
sanghoshinf25d2e02015-11-11 23:07:17 +0900215 deviceService.getAvailableDevices().forEach(d -> {
216 if (!d.equals(device)) {
217 deviceService.getPorts(d.id()).forEach(p -> {
Daniel Park23193902016-03-24 18:17:19 +0900218 String pName = p.annotations().value(PORT_NAME);
sanghoshinf25d2e02015-11-11 23:07:17 +0900219 if (!p.equals(port) && vni.equals(getVniForPort(pName))) {
Daniel Park23193902016-03-24 18:17:19 +0900220 Ip4Address hostxDpIpAddress = config.nodes().get(d.id());
221
sanghoshinf25d2e02015-11-11 23:07:17 +0900222 Ip4Address fixedIpx = getFixedIpAddressForPort(pName);
Daniel Park23193902016-03-24 18:17:19 +0900223 if (port.isEnabled()) {
224 setVxLanFlowRule(vni, device.id(), hostxDpIpAddress, fixedIpx);
225 setVxLanFlowRule(vni, d.id(), hostDpIpAddress, fixedIp);
sanghoshin65723ae2015-11-17 22:07:21 +0900226 }
sanghoshinf25d2e02015-11-11 23:07:17 +0900227 }
228 });
229 }
230 });
sanghoshin94872a12015-10-16 18:04:34 +0900231 }
232
233 /**
Daniel Park5df65182016-01-09 00:12:03 +0900234 * Sets the flow rules between traffic from VMs in different Cnode.
235 *
236 * @param vni VNI
237 * @param deviceId device ID
238 * @param hostIp host IP of the VM
239 * @param vmIp fixed IP of the VM
240 */
241 private void setVxLanFlowRule(String vni, DeviceId deviceId, Ip4Address hostIp,
242 Ip4Address vmIp) {
243 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
244 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
245
246 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
247 .matchTunnelId(Long.parseLong(vni))
248 .matchIPDst(vmIp.toIpPrefix());
249 tBuilder.extension(buildNiciraExtenstion(deviceId, hostIp), deviceId)
250 .setOutput(getTunnelPort(deviceId));
251
252 ForwardingObjective fo = DefaultForwardingObjective.builder()
253 .withSelector(sBuilder.build())
254 .withTreatment(tBuilder.build())
255 .withPriority(SWITCHING_RULE_PRIORITY)
256 .withFlag(ForwardingObjective.Flag.SPECIFIC)
257 .fromApp(appId)
258 .add();
259
260 flowObjectiveService.forward(deviceId, fo);
261 }
262
263 /**
264 * Returns OpenstackPort object for the Port reference given.
265 *
266 * @param port Port object
267 * @return OpenstackPort reference, or null when not found
268 */
269 public OpenstackPort openstackPort(Port port) {
Daniel Park23193902016-03-24 18:17:19 +0900270 String uuid = port.annotations().value(PORT_NAME).substring(3);
Daniel Park5df65182016-01-09 00:12:03 +0900271 return openstackPortList.stream().filter(p -> p.id().startsWith(uuid))
272 .findAny().orElse(null);
273 }
274
275 /**
276 * Remove flows rules for the removed VM.
277 *
278 * @param removedPort removedport info
279 * @param openstackPortInfoMap openstackPortInfoMap
280 */
sangho93447f12016-02-24 00:33:22 +0900281 public void removeSwitchingRules(Port removedPort, Map<String,
sangho3623cb62016-01-15 22:06:38 +0900282 OpenstackPortInfo> openstackPortInfoMap) {
Daniel Park5df65182016-01-09 00:12:03 +0900283 OpenstackPortInfo openstackPortInfo = openstackPortInfoMap
Daniel Park23193902016-03-24 18:17:19 +0900284 .get(removedPort.annotations().value(PORT_NAME));
Daniel Park5df65182016-01-09 00:12:03 +0900285
286 DeviceId deviceId = openstackPortInfo.deviceId();
287 Ip4Address vmIp = openstackPortInfo.ip();
288 PortNumber portNumber = removedPort.number();
289 long vni = openstackPortInfo.vni();
290
291 removeFlowRuleForTunnelTag(deviceId, portNumber);
292 removeFlowRuleForVMsInSameCnode(deviceId, vmIp, vni);
293 removeFlowRuleForVMsInDiffrentCnode(removedPort, deviceId, vmIp, vni, openstackPortInfoMap);
294 }
295
296 /**
297 * Removes flow rules for tagging tunnelId.
298 *
299 * @param deviceId device id
300 * @param portNumber port number
301 */
302 private void removeFlowRuleForTunnelTag(DeviceId deviceId, PortNumber portNumber) {
303 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
304 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
305
306 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
307 .matchInPort(portNumber);
308
309 ForwardingObjective fo = DefaultForwardingObjective.builder()
310 .withSelector(sBuilder.build())
311 .withTreatment(tBuilder.build())
312 .withPriority(TUNNELTAG_RULE_PRIORITY)
313 .withFlag(ForwardingObjective.Flag.SPECIFIC)
314 .fromApp(appId)
315 .remove();
316
317 flowObjectiveService.forward(deviceId, fo);
318 }
319
320 /**
321 * Removes the flow rules for traffic between VMs in the same Cnode.
322 *
323 * @param deviceId device id on which removed VM was run
324 * @param vmIp ip of the removed VM
325 * @param vni vni which removed VM was belonged
326 */
327 private void removeFlowRuleForVMsInSameCnode(DeviceId deviceId, Ip4Address vmIp, long vni) {
328 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
329
330 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
331 .matchIPDst(vmIp.toIpPrefix())
332 .matchTunnelId(vni);
333
334 ForwardingObjective fo = DefaultForwardingObjective.builder()
335 .withSelector(sBuilder.build())
336 .withTreatment(DefaultTrafficTreatment.builder().build())
337 .withFlag(ForwardingObjective.Flag.SPECIFIC)
338 .withPriority(SWITCHING_RULE_PRIORITY)
339 .fromApp(appId)
340 .remove();
341
342 flowObjectiveService.forward(deviceId, fo);
343 }
344
345 /**
346 * Removes the flow rules for traffic between VMs in the different Cnode.
347 *
348 * @param removedPort removedport info
349 * @param deviceId device id on which removed VM was run
350 * @param vmIp ip of the removed VM
351 * @param vni vni which removed VM was belonged
352 * @param openstackPortInfoMap openstackPortInfoMap
353 */
354 private void removeFlowRuleForVMsInDiffrentCnode(Port removedPort, DeviceId deviceId, Ip4Address vmIp,
355 long vni, Map<String, OpenstackPortInfo> openstackPortInfoMap) {
356
357 final boolean anyPortRemainedInSameCnode
358 = checkIfAnyPortRemainedInSameCnode(removedPort, deviceId, vni, openstackPortInfoMap);
359
360 openstackPortInfoMap.forEach((port, portInfo) -> {
361 if (portInfo.vni() == vni && !portInfo.deviceId().equals(deviceId)) {
362 removeVxLanFlowRule(portInfo.deviceId(), vmIp, vni);
363 if (!anyPortRemainedInSameCnode) {
364 removeVxLanFlowRule(deviceId, portInfo.ip(), vni);
365 }
366 }
367 });
368 }
369
370 /**
371 * Removes the flow rules between traffic from VMs in different Cnode.
372 *
373 * @param deviceId device id
374 * @param vmIp ip
375 * @param vni vni which removed VM was belonged
376 */
377 private void removeVxLanFlowRule(DeviceId deviceId, Ip4Address vmIp, long vni) {
378 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
379
380 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
381 .matchTunnelId(vni)
382 .matchIPDst(vmIp.toIpPrefix());
383
384 ForwardingObjective fo = DefaultForwardingObjective.builder()
385 .withSelector(sBuilder.build())
386 .withTreatment(DefaultTrafficTreatment.builder().build())
387 .withFlag(ForwardingObjective.Flag.SPECIFIC)
388 .withPriority(SWITCHING_RULE_PRIORITY)
389 .fromApp(appId)
390 .remove();
391
392 flowObjectiveService.forward(deviceId, fo);
393 }
394
395 /**
396 * Checks if there is any port remained with same vni at the device, on which the removed VM was run.
397 *
398 * @param removedPort removedport info
399 * @param deviceId device id on which removed VM was run
400 * @param vni vni which removed VM was belonged
401 * @param openstackPortInfoMap openstackPortInfoMap
402 * @return true if there is, false otherwise
403 */
404 private boolean checkIfAnyPortRemainedInSameCnode(Port removedPort, DeviceId deviceId, long vni,
405 Map<String, OpenstackPortInfo> openstackPortInfoMap) {
406
407 for (Map.Entry<String, OpenstackPortInfo> entry : openstackPortInfoMap.entrySet()) {
Daniel Park23193902016-03-24 18:17:19 +0900408 if (!removedPort.annotations().value(PORT_NAME).equals(entry.getKey())) {
Daniel Park5df65182016-01-09 00:12:03 +0900409 if (entry.getValue().vni() == vni && entry.getValue().deviceId().equals(deviceId)) {
410 return true;
411 }
412 }
413 }
414 return false;
415 }
416
417 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900418 * Returns the VNI of the VM of the port.
sanghoshin94872a12015-10-16 18:04:34 +0900419 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900420 * @param portName VM port
421 * @return VNI
sanghoshin94872a12015-10-16 18:04:34 +0900422 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900423 private String getVniForPort(String portName) {
424 String uuid = portName.substring(3);
425 OpenstackPort port = openstackPortList.stream()
426 .filter(p -> p.id().startsWith(uuid))
427 .findAny().orElse(null);
428 if (port == null) {
daniel2a2bd7b2015-12-02 13:53:58 +0900429 log.debug("No port information for port {}", portName);
sanghoshinf25d2e02015-11-11 23:07:17 +0900430 return null;
431 }
sanghoshin94872a12015-10-16 18:04:34 +0900432
sanghoshinf25d2e02015-11-11 23:07:17 +0900433 OpenstackNetwork network = openstackNetworkList.stream()
434 .filter(n -> n.id().equals(port.networkId()))
435 .findAny().orElse(null);
436 if (network == null) {
Satish K2e2d6352015-11-27 12:02:15 +0530437 log.warn("No VNI information for network {}", port.networkId());
sanghoshinf25d2e02015-11-11 23:07:17 +0900438 return null;
439 }
sanghoshin94872a12015-10-16 18:04:34 +0900440
sanghoshinf25d2e02015-11-11 23:07:17 +0900441 return network.segmentId();
sanghoshin94872a12015-10-16 18:04:34 +0900442 }
443
444 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900445 * Returns the Fixed IP address of the VM.
sanghoshin94872a12015-10-16 18:04:34 +0900446 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900447 * @param portName VM port info
448 * @return IP address of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900449 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900450 private Ip4Address getFixedIpAddressForPort(String portName) {
sanghoshin94872a12015-10-16 18:04:34 +0900451
sanghoshinf25d2e02015-11-11 23:07:17 +0900452 String uuid = portName.substring(3);
453 OpenstackPort port = openstackPortList.stream()
454 .filter(p -> p.id().startsWith(uuid))
455 .findFirst().orElse(null);
sanghoshin94872a12015-10-16 18:04:34 +0900456
sanghoshinf25d2e02015-11-11 23:07:17 +0900457 if (port == null) {
458 log.error("There is no port information for port name {}", portName);
459 return null;
460 }
sanghoshin94872a12015-10-16 18:04:34 +0900461
sanghoshinf25d2e02015-11-11 23:07:17 +0900462 if (port.fixedIps().isEmpty()) {
463 log.error("There is no fixed IP info in the port information");
464 return null;
465 }
466
467 return (Ip4Address) port.fixedIps().values().toArray()[0];
468 }
469
sanghoshinf25d2e02015-11-11 23:07:17 +0900470 private ExtensionTreatment buildNiciraExtenstion(DeviceId id, Ip4Address hostIp) {
471 Driver driver = driverService.getDriver(id);
472 DriverHandler driverHandler = new DefaultDriverHandler(new DefaultDriverData(driver, id));
473 ExtensionTreatmentResolver resolver = driverHandler.behaviour(ExtensionTreatmentResolver.class);
474
475 ExtensionTreatment extensionInstruction =
476 resolver.getExtensionInstruction(
477 ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type());
478
479 try {
Daniel Park23193902016-03-24 18:17:19 +0900480 extensionInstruction.setPropertyValue(TUNNEL_DST, hostIp);
sanghoshinf25d2e02015-11-11 23:07:17 +0900481 } catch (ExtensionPropertyException e) {
482 log.error("Error setting Nicira extension setting {}", e);
483 }
484
485 return extensionInstruction;
486 }
487
Daniel Park5df65182016-01-09 00:12:03 +0900488 private PortNumber getTunnelPort(DeviceId deviceId) {
489 Port port = deviceService.getPorts(deviceId).stream()
Daniel Park23193902016-03-24 18:17:19 +0900490 .filter(p -> p.annotations().value(PORT_NAME).equals(
sanghoshin46c6e3e2015-12-18 18:42:17 +0900491 OpenstackSwitchingManager.PORTNAME_PREFIX_TUNNEL))
sanghoshinf25d2e02015-11-11 23:07:17 +0900492 .findAny().orElse(null);
493
494 if (port == null) {
495 log.error("No TunnelPort was created.");
496 return null;
497 }
498 return port.number();
499 }
sangho90088532016-02-25 18:06:12 +0900500
sanghoshin94872a12015-10-16 18:04:34 +0900501}