blob: 5f072bdcaf45312c99771f9ce4aef06bcd82006e [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;
sangho48907542016-03-28 16:07:07 +090046import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
sangho0c2a3da2016-02-16 13:39:07 +090047import org.onosproject.openstacknetworking.OpenstackPortInfo;
sanghoshin94872a12015-10-16 18:04:34 +090048import org.slf4j.Logger;
49import org.slf4j.LoggerFactory;
50
sanghoshinf25d2e02015-11-11 23:07:17 +090051import java.util.Collection;
Daniel Park5df65182016-01-09 00:12:03 +090052import java.util.Map;
sanghoshinf25d2e02015-11-11 23:07:17 +090053
sanghoshin94872a12015-10-16 18:04:34 +090054/**
sanghoshin46297d22015-11-03 17:51:24 +090055 * Populates switching flow rules.
sanghoshin94872a12015-10-16 18:04:34 +090056 */
57public class OpenstackSwitchingRulePopulator {
58
59 private static Logger log = LoggerFactory
60 .getLogger(OpenstackSwitchingRulePopulator.class);
daniel2a2bd7b2015-12-02 13:53:58 +090061 private static final int SWITCHING_RULE_PRIORITY = 30000;
daniel2a2bd7b2015-12-02 13:53:58 +090062 private static final int TUNNELTAG_RULE_PRIORITY = 30000;
Daniel Park23193902016-03-24 18:17:19 +090063 private static final String PORT_NAME = "portName";
64 private static final String TUNNEL_DST = "tunnelDst";
sanghoshin94872a12015-10-16 18:04:34 +090065 private FlowObjectiveService flowObjectiveService;
sanghoshinf25d2e02015-11-11 23:07:17 +090066 private DriverService driverService;
67 private DeviceService deviceService;
sanghoshin94872a12015-10-16 18:04:34 +090068 private ApplicationId appId;
sangho48907542016-03-28 16:07:07 +090069 private OpenstackNetworkingConfig config;
sanghoshin94872a12015-10-16 18:04:34 +090070
sanghoshinf25d2e02015-11-11 23:07:17 +090071 private Collection<OpenstackNetwork> openstackNetworkList;
72 private Collection<OpenstackPort> openstackPortList;
73
sanghoshin94872a12015-10-16 18:04:34 +090074 /**
Ray Milkey87b16b02015-10-30 11:50:00 -070075 * Creates OpenstackSwitchingRulPopulator.
76 *
77 * @param appId application id
sanghoshin94872a12015-10-16 18:04:34 +090078 * @param flowObjectiveService FlowObjectiveService reference
sanghoshinf25d2e02015-11-11 23:07:17 +090079 * @param deviceService DeviceService reference
Hyunsun Moon0dba61f2016-03-03 14:05:21 -080080 * @param openstackService openstack interface service
sanghoshinf25d2e02015-11-11 23:07:17 +090081 * @param driverService DriverService reference
Daniel Park23193902016-03-24 18:17:19 +090082 * @param config OpenstackRoutingConfig
sanghoshin94872a12015-10-16 18:04:34 +090083 */
84 public OpenstackSwitchingRulePopulator(ApplicationId appId,
sanghoshinf25d2e02015-11-11 23:07:17 +090085 FlowObjectiveService flowObjectiveService,
86 DeviceService deviceService,
sangho93447f12016-02-24 00:33:22 +090087 OpenstackInterfaceService openstackService,
Daniel Park23193902016-03-24 18:17:19 +090088 DriverService driverService,
sangho48907542016-03-28 16:07:07 +090089 OpenstackNetworkingConfig config) {
sanghoshin94872a12015-10-16 18:04:34 +090090 this.flowObjectiveService = flowObjectiveService;
sanghoshinf25d2e02015-11-11 23:07:17 +090091 this.deviceService = deviceService;
92 this.driverService = driverService;
sanghoshin94872a12015-10-16 18:04:34 +090093 this.appId = appId;
Daniel Park23193902016-03-24 18:17:19 +090094 this.config = config;
sanghoshinf25d2e02015-11-11 23:07:17 +090095
sangho0c2a3da2016-02-16 13:39:07 +090096 openstackNetworkList = openstackService.networks();
97 openstackPortList = openstackService.ports();
sanghoshin94872a12015-10-16 18:04:34 +090098 }
99
daniel2a2bd7b2015-12-02 13:53:58 +0900100
sanghoshin94872a12015-10-16 18:04:34 +0900101 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900102 * Populates flow rules for the VM created.
sanghoshin94872a12015-10-16 18:04:34 +0900103 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900104 * @param device device to populate rules to
105 * @param port port for the VM created
sanghoshin94872a12015-10-16 18:04:34 +0900106 */
sangho93447f12016-02-24 00:33:22 +0900107 public void populateSwitchingRules(Device device, Port port) {
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800108 populateFlowRulesForTunnelTag(device, port);
sanghoshinf25d2e02015-11-11 23:07:17 +0900109 populateFlowRulesForTrafficToSameCnode(device, port);
110 populateFlowRulesForTrafficToDifferentCnode(device, port);
sanghoshin94872a12015-10-16 18:04:34 +0900111 }
112
113 /**
daniel2a2bd7b2015-12-02 13:53:58 +0900114 * Populate the flow rules for tagging tunnelId according to which inport is came from.
115 *
116 * @param device device to put the rules
117 * @param port port info of the VM
118 */
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800119 private void populateFlowRulesForTunnelTag(Device device, Port port) {
Daniel Park23193902016-03-24 18:17:19 +0900120 Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value(PORT_NAME));
121 String portName = port.annotations().value(PORT_NAME);
daniel2a2bd7b2015-12-02 13:53:58 +0900122 String vni = getVniForPort(portName);
123
124 if (vmIp != null) {
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800125 setFlowRuleForTunnelTag(device.id(), port, vni);
daniel2a2bd7b2015-12-02 13:53:58 +0900126 }
127 }
128
Daniel Park5df65182016-01-09 00:12:03 +0900129 private void setFlowRuleForTunnelTag(DeviceId deviceId, Port port, String vni) {
sanghoshin075e3e72015-11-25 16:34:29 +0900130
Daniel Park5df65182016-01-09 00:12:03 +0900131 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
132 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
133
134 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
135 .matchInPort(port.number());
136
137 tBuilder.setTunnelId(Long.parseLong(vni));
138
139 ForwardingObjective fo = DefaultForwardingObjective.builder()
140 .withSelector(sBuilder.build())
141 .withTreatment(tBuilder.build())
142 .withPriority(TUNNELTAG_RULE_PRIORITY)
143 .withFlag(ForwardingObjective.Flag.SPECIFIC)
144 .fromApp(appId)
145 .add();
146
147 flowObjectiveService.forward(deviceId, fo);
sanghoshin65723ae2015-11-17 22:07:21 +0900148 }
149
150 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900151 * Populates the flow rules for traffic to VMs in the same Cnode as the sender.
sanghoshin94872a12015-10-16 18:04:34 +0900152 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900153 * @param device device to put the rules
154 * @param port port info of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900155 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900156 private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) {
Daniel Park23193902016-03-24 18:17:19 +0900157 Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value(PORT_NAME));
158 String portName = port.annotations().value(PORT_NAME);
daniel2a2bd7b2015-12-02 13:53:58 +0900159 String vni = getVniForPort(portName);
daniel2a2bd7b2015-12-02 13:53:58 +0900160
sanghoshinf25d2e02015-11-11 23:07:17 +0900161 if (vmIp != null) {
Daniel Park5df65182016-01-09 00:12:03 +0900162 setFlowRuleForVMsInSameCnode(vmIp, device.id(), port, vni);
sanghoshinf25d2e02015-11-11 23:07:17 +0900163 }
sanghoshin94872a12015-10-16 18:04:34 +0900164 }
165
166 /**
Daniel Park5df65182016-01-09 00:12:03 +0900167 * Sets the flow rules for traffic between VMs in the same Cnode.
168 *
169 * @param ip4Address VM IP address
170 * @param id device ID to put rules
171 * @param port VM port
172 * @param vni VM VNI
173 */
174 private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id,
175 Port port, String vni) {
176
177 //For L2 Switching Case
178 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
179 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
180
181 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
182 .matchIPDst(ip4Address.toIpPrefix())
183 .matchTunnelId(Long.parseLong(vni));
184
185 tBuilder.setOutput(port.number());
186
187 ForwardingObjective fo = DefaultForwardingObjective.builder()
188 .withSelector(sBuilder.build())
189 .withTreatment(tBuilder.build())
190 .withPriority(SWITCHING_RULE_PRIORITY)
191 .withFlag(ForwardingObjective.Flag.SPECIFIC)
192 .fromApp(appId)
193 .add();
194
195 flowObjectiveService.forward(id, fo);
196 }
197
198 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900199 * Populates the flow rules for traffic to VMs in different Cnode using
200 * Nicira extention.
sanghoshin94872a12015-10-16 18:04:34 +0900201 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900202 * @param device device to put rules
203 * @param port port information of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900204 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900205 private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) {
Daniel Park23193902016-03-24 18:17:19 +0900206 String portName = port.annotations().value(PORT_NAME);
sanghoshinf25d2e02015-11-11 23:07:17 +0900207 Ip4Address fixedIp = getFixedIpAddressForPort(portName);
sanghoshinf25d2e02015-11-11 23:07:17 +0900208 String vni = getVniForPort(portName);
Daniel Park23193902016-03-24 18:17:19 +0900209 Ip4Address hostDpIpAddress = config.nodes().get(device.id());
210
211 if (hostDpIpAddress == null) {
212 log.debug("There's no openstack node information for device id {}", device.id().toString());
213 return;
214 }
215
sanghoshinf25d2e02015-11-11 23:07:17 +0900216 deviceService.getAvailableDevices().forEach(d -> {
217 if (!d.equals(device)) {
218 deviceService.getPorts(d.id()).forEach(p -> {
Daniel Park23193902016-03-24 18:17:19 +0900219 String pName = p.annotations().value(PORT_NAME);
sanghoshinf25d2e02015-11-11 23:07:17 +0900220 if (!p.equals(port) && vni.equals(getVniForPort(pName))) {
Daniel Park23193902016-03-24 18:17:19 +0900221 Ip4Address hostxDpIpAddress = config.nodes().get(d.id());
222
sanghoshinf25d2e02015-11-11 23:07:17 +0900223 Ip4Address fixedIpx = getFixedIpAddressForPort(pName);
Daniel Park23193902016-03-24 18:17:19 +0900224 if (port.isEnabled()) {
225 setVxLanFlowRule(vni, device.id(), hostxDpIpAddress, fixedIpx);
226 setVxLanFlowRule(vni, d.id(), hostDpIpAddress, fixedIp);
sanghoshin65723ae2015-11-17 22:07:21 +0900227 }
sanghoshinf25d2e02015-11-11 23:07:17 +0900228 }
229 });
230 }
231 });
sanghoshin94872a12015-10-16 18:04:34 +0900232 }
233
234 /**
Daniel Park5df65182016-01-09 00:12:03 +0900235 * Sets the flow rules between traffic from VMs in different Cnode.
236 *
237 * @param vni VNI
238 * @param deviceId device ID
239 * @param hostIp host IP of the VM
240 * @param vmIp fixed IP of the VM
241 */
242 private void setVxLanFlowRule(String vni, DeviceId deviceId, Ip4Address hostIp,
243 Ip4Address vmIp) {
244 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
245 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
246
247 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
248 .matchTunnelId(Long.parseLong(vni))
249 .matchIPDst(vmIp.toIpPrefix());
250 tBuilder.extension(buildNiciraExtenstion(deviceId, hostIp), deviceId)
251 .setOutput(getTunnelPort(deviceId));
252
253 ForwardingObjective fo = DefaultForwardingObjective.builder()
254 .withSelector(sBuilder.build())
255 .withTreatment(tBuilder.build())
256 .withPriority(SWITCHING_RULE_PRIORITY)
257 .withFlag(ForwardingObjective.Flag.SPECIFIC)
258 .fromApp(appId)
259 .add();
260
261 flowObjectiveService.forward(deviceId, fo);
262 }
263
264 /**
265 * Returns OpenstackPort object for the Port reference given.
266 *
267 * @param port Port object
268 * @return OpenstackPort reference, or null when not found
269 */
270 public OpenstackPort openstackPort(Port port) {
Daniel Park23193902016-03-24 18:17:19 +0900271 String uuid = port.annotations().value(PORT_NAME).substring(3);
Daniel Park5df65182016-01-09 00:12:03 +0900272 return openstackPortList.stream().filter(p -> p.id().startsWith(uuid))
273 .findAny().orElse(null);
274 }
275
276 /**
277 * Remove flows rules for the removed VM.
278 *
279 * @param removedPort removedport info
280 * @param openstackPortInfoMap openstackPortInfoMap
281 */
sangho93447f12016-02-24 00:33:22 +0900282 public void removeSwitchingRules(Port removedPort, Map<String,
sangho3623cb62016-01-15 22:06:38 +0900283 OpenstackPortInfo> openstackPortInfoMap) {
Daniel Park5df65182016-01-09 00:12:03 +0900284 OpenstackPortInfo openstackPortInfo = openstackPortInfoMap
Daniel Park23193902016-03-24 18:17:19 +0900285 .get(removedPort.annotations().value(PORT_NAME));
Daniel Park5df65182016-01-09 00:12:03 +0900286
287 DeviceId deviceId = openstackPortInfo.deviceId();
288 Ip4Address vmIp = openstackPortInfo.ip();
289 PortNumber portNumber = removedPort.number();
290 long vni = openstackPortInfo.vni();
291
292 removeFlowRuleForTunnelTag(deviceId, portNumber);
293 removeFlowRuleForVMsInSameCnode(deviceId, vmIp, vni);
294 removeFlowRuleForVMsInDiffrentCnode(removedPort, deviceId, vmIp, vni, openstackPortInfoMap);
295 }
296
297 /**
298 * Removes flow rules for tagging tunnelId.
299 *
300 * @param deviceId device id
301 * @param portNumber port number
302 */
303 private void removeFlowRuleForTunnelTag(DeviceId deviceId, PortNumber portNumber) {
304 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
305 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
306
307 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
308 .matchInPort(portNumber);
309
310 ForwardingObjective fo = DefaultForwardingObjective.builder()
311 .withSelector(sBuilder.build())
312 .withTreatment(tBuilder.build())
313 .withPriority(TUNNELTAG_RULE_PRIORITY)
314 .withFlag(ForwardingObjective.Flag.SPECIFIC)
315 .fromApp(appId)
316 .remove();
317
318 flowObjectiveService.forward(deviceId, fo);
319 }
320
321 /**
322 * Removes the flow rules for traffic between VMs in the same Cnode.
323 *
324 * @param deviceId device id on which removed VM was run
325 * @param vmIp ip of the removed VM
326 * @param vni vni which removed VM was belonged
327 */
328 private void removeFlowRuleForVMsInSameCnode(DeviceId deviceId, Ip4Address vmIp, long vni) {
329 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
330
331 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
332 .matchIPDst(vmIp.toIpPrefix())
333 .matchTunnelId(vni);
334
335 ForwardingObjective fo = DefaultForwardingObjective.builder()
336 .withSelector(sBuilder.build())
337 .withTreatment(DefaultTrafficTreatment.builder().build())
338 .withFlag(ForwardingObjective.Flag.SPECIFIC)
339 .withPriority(SWITCHING_RULE_PRIORITY)
340 .fromApp(appId)
341 .remove();
342
343 flowObjectiveService.forward(deviceId, fo);
344 }
345
346 /**
347 * Removes the flow rules for traffic between VMs in the different Cnode.
348 *
349 * @param removedPort removedport info
350 * @param deviceId device id on which removed VM was run
351 * @param vmIp ip of the removed VM
352 * @param vni vni which removed VM was belonged
353 * @param openstackPortInfoMap openstackPortInfoMap
354 */
355 private void removeFlowRuleForVMsInDiffrentCnode(Port removedPort, DeviceId deviceId, Ip4Address vmIp,
356 long vni, Map<String, OpenstackPortInfo> openstackPortInfoMap) {
357
358 final boolean anyPortRemainedInSameCnode
359 = checkIfAnyPortRemainedInSameCnode(removedPort, deviceId, vni, openstackPortInfoMap);
360
361 openstackPortInfoMap.forEach((port, portInfo) -> {
362 if (portInfo.vni() == vni && !portInfo.deviceId().equals(deviceId)) {
363 removeVxLanFlowRule(portInfo.deviceId(), vmIp, vni);
364 if (!anyPortRemainedInSameCnode) {
365 removeVxLanFlowRule(deviceId, portInfo.ip(), vni);
366 }
367 }
368 });
369 }
370
371 /**
372 * Removes the flow rules between traffic from VMs in different Cnode.
373 *
374 * @param deviceId device id
375 * @param vmIp ip
376 * @param vni vni which removed VM was belonged
377 */
378 private void removeVxLanFlowRule(DeviceId deviceId, Ip4Address vmIp, long vni) {
379 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
380
381 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
382 .matchTunnelId(vni)
383 .matchIPDst(vmIp.toIpPrefix());
384
385 ForwardingObjective fo = DefaultForwardingObjective.builder()
386 .withSelector(sBuilder.build())
387 .withTreatment(DefaultTrafficTreatment.builder().build())
388 .withFlag(ForwardingObjective.Flag.SPECIFIC)
389 .withPriority(SWITCHING_RULE_PRIORITY)
390 .fromApp(appId)
391 .remove();
392
393 flowObjectiveService.forward(deviceId, fo);
394 }
395
396 /**
397 * Checks if there is any port remained with same vni at the device, on which the removed VM was run.
398 *
399 * @param removedPort removedport info
400 * @param deviceId device id on which removed VM was run
401 * @param vni vni which removed VM was belonged
402 * @param openstackPortInfoMap openstackPortInfoMap
403 * @return true if there is, false otherwise
404 */
405 private boolean checkIfAnyPortRemainedInSameCnode(Port removedPort, DeviceId deviceId, long vni,
406 Map<String, OpenstackPortInfo> openstackPortInfoMap) {
407
408 for (Map.Entry<String, OpenstackPortInfo> entry : openstackPortInfoMap.entrySet()) {
Daniel Park23193902016-03-24 18:17:19 +0900409 if (!removedPort.annotations().value(PORT_NAME).equals(entry.getKey())) {
Daniel Park5df65182016-01-09 00:12:03 +0900410 if (entry.getValue().vni() == vni && entry.getValue().deviceId().equals(deviceId)) {
411 return true;
412 }
413 }
414 }
415 return false;
416 }
417
418 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900419 * Returns the VNI of the VM of the port.
sanghoshin94872a12015-10-16 18:04:34 +0900420 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900421 * @param portName VM port
422 * @return VNI
sanghoshin94872a12015-10-16 18:04:34 +0900423 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900424 private String getVniForPort(String portName) {
425 String uuid = portName.substring(3);
426 OpenstackPort port = openstackPortList.stream()
427 .filter(p -> p.id().startsWith(uuid))
428 .findAny().orElse(null);
429 if (port == null) {
daniel2a2bd7b2015-12-02 13:53:58 +0900430 log.debug("No port information for port {}", portName);
sanghoshinf25d2e02015-11-11 23:07:17 +0900431 return null;
432 }
sanghoshin94872a12015-10-16 18:04:34 +0900433
sanghoshinf25d2e02015-11-11 23:07:17 +0900434 OpenstackNetwork network = openstackNetworkList.stream()
435 .filter(n -> n.id().equals(port.networkId()))
436 .findAny().orElse(null);
437 if (network == null) {
Satish K2e2d6352015-11-27 12:02:15 +0530438 log.warn("No VNI information for network {}", port.networkId());
sanghoshinf25d2e02015-11-11 23:07:17 +0900439 return null;
440 }
sanghoshin94872a12015-10-16 18:04:34 +0900441
sanghoshinf25d2e02015-11-11 23:07:17 +0900442 return network.segmentId();
sanghoshin94872a12015-10-16 18:04:34 +0900443 }
444
445 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900446 * Returns the Fixed IP address of the VM.
sanghoshin94872a12015-10-16 18:04:34 +0900447 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900448 * @param portName VM port info
449 * @return IP address of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900450 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900451 private Ip4Address getFixedIpAddressForPort(String portName) {
sanghoshin94872a12015-10-16 18:04:34 +0900452
sanghoshinf25d2e02015-11-11 23:07:17 +0900453 String uuid = portName.substring(3);
454 OpenstackPort port = openstackPortList.stream()
455 .filter(p -> p.id().startsWith(uuid))
456 .findFirst().orElse(null);
sanghoshin94872a12015-10-16 18:04:34 +0900457
sanghoshinf25d2e02015-11-11 23:07:17 +0900458 if (port == null) {
459 log.error("There is no port information for port name {}", portName);
460 return null;
461 }
sanghoshin94872a12015-10-16 18:04:34 +0900462
sanghoshinf25d2e02015-11-11 23:07:17 +0900463 if (port.fixedIps().isEmpty()) {
464 log.error("There is no fixed IP info in the port information");
465 return null;
466 }
467
468 return (Ip4Address) port.fixedIps().values().toArray()[0];
469 }
470
sanghoshinf25d2e02015-11-11 23:07:17 +0900471 private ExtensionTreatment buildNiciraExtenstion(DeviceId id, Ip4Address hostIp) {
472 Driver driver = driverService.getDriver(id);
473 DriverHandler driverHandler = new DefaultDriverHandler(new DefaultDriverData(driver, id));
474 ExtensionTreatmentResolver resolver = driverHandler.behaviour(ExtensionTreatmentResolver.class);
475
476 ExtensionTreatment extensionInstruction =
477 resolver.getExtensionInstruction(
478 ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type());
479
480 try {
Daniel Park23193902016-03-24 18:17:19 +0900481 extensionInstruction.setPropertyValue(TUNNEL_DST, hostIp);
sanghoshinf25d2e02015-11-11 23:07:17 +0900482 } catch (ExtensionPropertyException e) {
483 log.error("Error setting Nicira extension setting {}", e);
484 }
485
486 return extensionInstruction;
487 }
488
Daniel Park5df65182016-01-09 00:12:03 +0900489 private PortNumber getTunnelPort(DeviceId deviceId) {
490 Port port = deviceService.getPorts(deviceId).stream()
Daniel Park23193902016-03-24 18:17:19 +0900491 .filter(p -> p.annotations().value(PORT_NAME).equals(
sanghoshin46c6e3e2015-12-18 18:42:17 +0900492 OpenstackSwitchingManager.PORTNAME_PREFIX_TUNNEL))
sanghoshinf25d2e02015-11-11 23:07:17 +0900493 .findAny().orElse(null);
494
495 if (port == null) {
496 log.error("No TunnelPort was created.");
497 return null;
498 }
499 return port.number();
500 }
sangho90088532016-02-25 18:06:12 +0900501
sanghoshin94872a12015-10-16 18:04:34 +0900502}