blob: 258b24ca934f70edf7e498408b4b6c4441f2352a [file] [log] [blame]
sanghoshin94872a12015-10-16 18:04:34 +09001/*
2* Copyright 2015 Open Networking Laboratory
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*/
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;
sangho0c2a3da2016-02-16 13:39:07 +090043import org.onosproject.openstacknetworking.OpenstackNetwork;
44import org.onosproject.openstacknetworking.OpenstackNetworkingService;
45import org.onosproject.openstacknetworking.OpenstackPort;
46import 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;
61 private static final int EAST_WEST_ROUTING_RULE_PRIORITY = 29000;
62 private static final int TUNNELTAG_RULE_PRIORITY = 30000;
sanghoshin94872a12015-10-16 18:04:34 +090063
64 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;
68
sanghoshinf25d2e02015-11-11 23:07:17 +090069 private Collection<OpenstackNetwork> openstackNetworkList;
70 private Collection<OpenstackPort> openstackPortList;
71
sanghoshin94872a12015-10-16 18:04:34 +090072 /**
Ray Milkey87b16b02015-10-30 11:50:00 -070073 * Creates OpenstackSwitchingRulPopulator.
74 *
75 * @param appId application id
sanghoshin94872a12015-10-16 18:04:34 +090076 * @param flowObjectiveService FlowObjectiveService reference
sanghoshinf25d2e02015-11-11 23:07:17 +090077 * @param deviceService DeviceService reference
78 * @param driverService DriverService reference
sanghoshin94872a12015-10-16 18:04:34 +090079 */
80 public OpenstackSwitchingRulePopulator(ApplicationId appId,
sanghoshinf25d2e02015-11-11 23:07:17 +090081 FlowObjectiveService flowObjectiveService,
82 DeviceService deviceService,
sangho0c2a3da2016-02-16 13:39:07 +090083 OpenstackNetworkingService openstackService,
sanghoshinf25d2e02015-11-11 23:07:17 +090084 DriverService driverService) {
sanghoshin94872a12015-10-16 18:04:34 +090085 this.flowObjectiveService = flowObjectiveService;
sanghoshinf25d2e02015-11-11 23:07:17 +090086 this.deviceService = deviceService;
87 this.driverService = driverService;
sanghoshin94872a12015-10-16 18:04:34 +090088 this.appId = appId;
sanghoshinf25d2e02015-11-11 23:07:17 +090089
sangho0c2a3da2016-02-16 13:39:07 +090090 openstackNetworkList = openstackService.networks();
91 openstackPortList = openstackService.ports();
sanghoshin94872a12015-10-16 18:04:34 +090092 }
93
daniel2a2bd7b2015-12-02 13:53:58 +090094
sanghoshin94872a12015-10-16 18:04:34 +090095 /**
sanghoshinf25d2e02015-11-11 23:07:17 +090096 * Populates flow rules for the VM created.
sanghoshin94872a12015-10-16 18:04:34 +090097 *
Thomas Vachuska708d3032016-02-18 11:11:46 -080098 * @param doNotPushFlow true to suppress push of initial flows
sanghoshinf25d2e02015-11-11 23:07:17 +090099 * @param device device to populate rules to
100 * @param port port for the VM created
sanghoshin94872a12015-10-16 18:04:34 +0900101 */
sangho3623cb62016-01-15 22:06:38 +0900102 public void populateSwitchingRules(boolean doNotPushFlow, Device device, Port port) {
103 if (doNotPushFlow) {
104 return;
105 }
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800106 populateFlowRulesForTunnelTag(device, port);
sanghoshinf25d2e02015-11-11 23:07:17 +0900107 populateFlowRulesForTrafficToSameCnode(device, port);
108 populateFlowRulesForTrafficToDifferentCnode(device, port);
sanghoshin94872a12015-10-16 18:04:34 +0900109 }
110
111 /**
daniel2a2bd7b2015-12-02 13:53:58 +0900112 * Populate the flow rules for tagging tunnelId according to which inport is came from.
113 *
114 * @param device device to put the rules
115 * @param port port info of the VM
116 */
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800117 private void populateFlowRulesForTunnelTag(Device device, Port port) {
daniel2a2bd7b2015-12-02 13:53:58 +0900118 Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName"));
119 String portName = port.annotations().value("portName");
120 String vni = getVniForPort(portName);
121
122 if (vmIp != null) {
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800123 setFlowRuleForTunnelTag(device.id(), port, vni);
daniel2a2bd7b2015-12-02 13:53:58 +0900124 }
125 }
126
Daniel Park5df65182016-01-09 00:12:03 +0900127 private void setFlowRuleForTunnelTag(DeviceId deviceId, Port port, String vni) {
sanghoshin075e3e72015-11-25 16:34:29 +0900128
Daniel Park5df65182016-01-09 00:12:03 +0900129 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
130 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
131
132 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
133 .matchInPort(port.number());
134
135 tBuilder.setTunnelId(Long.parseLong(vni));
136
137 ForwardingObjective fo = DefaultForwardingObjective.builder()
138 .withSelector(sBuilder.build())
139 .withTreatment(tBuilder.build())
140 .withPriority(TUNNELTAG_RULE_PRIORITY)
141 .withFlag(ForwardingObjective.Flag.SPECIFIC)
142 .fromApp(appId)
143 .add();
144
145 flowObjectiveService.forward(deviceId, fo);
sanghoshin65723ae2015-11-17 22:07:21 +0900146 }
147
148 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900149 * Populates the flow rules for traffic to VMs in the same Cnode as the sender.
sanghoshin94872a12015-10-16 18:04:34 +0900150 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900151 * @param device device to put the rules
152 * @param port port info of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900153 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900154 private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) {
155 Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName"));
daniel2a2bd7b2015-12-02 13:53:58 +0900156 String portName = port.annotations().value("portName");
157 String vni = getVniForPort(portName);
daniel2a2bd7b2015-12-02 13:53:58 +0900158
sanghoshinf25d2e02015-11-11 23:07:17 +0900159 if (vmIp != null) {
Daniel Park5df65182016-01-09 00:12:03 +0900160 setFlowRuleForVMsInSameCnode(vmIp, device.id(), port, vni);
sanghoshinf25d2e02015-11-11 23:07:17 +0900161 }
sanghoshin94872a12015-10-16 18:04:34 +0900162 }
163
164 /**
Daniel Park5df65182016-01-09 00:12:03 +0900165 * Sets the flow rules for traffic between VMs in the same Cnode.
166 *
167 * @param ip4Address VM IP address
168 * @param id device ID to put rules
169 * @param port VM port
170 * @param vni VM VNI
171 */
172 private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id,
173 Port port, String vni) {
174
175 //For L2 Switching Case
176 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
177 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
178
179 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
180 .matchIPDst(ip4Address.toIpPrefix())
181 .matchTunnelId(Long.parseLong(vni));
182
183 tBuilder.setOutput(port.number());
184
185 ForwardingObjective fo = DefaultForwardingObjective.builder()
186 .withSelector(sBuilder.build())
187 .withTreatment(tBuilder.build())
188 .withPriority(SWITCHING_RULE_PRIORITY)
189 .withFlag(ForwardingObjective.Flag.SPECIFIC)
190 .fromApp(appId)
191 .add();
192
193 flowObjectiveService.forward(id, fo);
194 }
195
196 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900197 * Populates the flow rules for traffic to VMs in different Cnode using
198 * Nicira extention.
sanghoshin94872a12015-10-16 18:04:34 +0900199 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900200 * @param device device to put rules
201 * @param port port information of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900202 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900203 private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) {
204 String portName = port.annotations().value("portName");
205 String channelId = device.annotations().value("channelId");
206 Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]);
207 Ip4Address fixedIp = getFixedIpAddressForPort(portName);
sanghoshinf25d2e02015-11-11 23:07:17 +0900208 String vni = getVniForPort(portName);
209 deviceService.getAvailableDevices().forEach(d -> {
210 if (!d.equals(device)) {
211 deviceService.getPorts(d.id()).forEach(p -> {
212 String pName = p.annotations().value("portName");
213 if (!p.equals(port) && vni.equals(getVniForPort(pName))) {
214 String cidx = d.annotations().value("channelId");
215 Ip4Address hostIpx = Ip4Address.valueOf(cidx.split(":")[0]);
sanghoshinf25d2e02015-11-11 23:07:17 +0900216 Ip4Address fixedIpx = getFixedIpAddressForPort(pName);
sanghoshin46c6e3e2015-12-18 18:42:17 +0900217 if (port.isEnabled() ||
218 port.annotations().value("portName").startsWith(
219 OpenstackSwitchingManager.PORTNAME_PREFIX_ROUTER)) {
Daniel Park5df65182016-01-09 00:12:03 +0900220 setVxLanFlowRule(vni, device.id(), hostIpx, fixedIpx);
221 setVxLanFlowRule(vni, d.id(), hostIpAddress, fixedIp);
sanghoshin65723ae2015-11-17 22:07:21 +0900222 }
sanghoshinf25d2e02015-11-11 23:07:17 +0900223 }
224 });
225 }
226 });
sanghoshin94872a12015-10-16 18:04:34 +0900227 }
228
229 /**
Daniel Park5df65182016-01-09 00:12:03 +0900230 * Sets the flow rules between traffic from VMs in different Cnode.
231 *
232 * @param vni VNI
233 * @param deviceId device ID
234 * @param hostIp host IP of the VM
235 * @param vmIp fixed IP of the VM
236 */
237 private void setVxLanFlowRule(String vni, DeviceId deviceId, Ip4Address hostIp,
238 Ip4Address vmIp) {
239 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
240 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
241
242 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
243 .matchTunnelId(Long.parseLong(vni))
244 .matchIPDst(vmIp.toIpPrefix());
245 tBuilder.extension(buildNiciraExtenstion(deviceId, hostIp), deviceId)
246 .setOutput(getTunnelPort(deviceId));
247
248 ForwardingObjective fo = DefaultForwardingObjective.builder()
249 .withSelector(sBuilder.build())
250 .withTreatment(tBuilder.build())
251 .withPriority(SWITCHING_RULE_PRIORITY)
252 .withFlag(ForwardingObjective.Flag.SPECIFIC)
253 .fromApp(appId)
254 .add();
255
256 flowObjectiveService.forward(deviceId, fo);
257 }
258
259 /**
260 * Returns OpenstackPort object for the Port reference given.
261 *
262 * @param port Port object
263 * @return OpenstackPort reference, or null when not found
264 */
265 public OpenstackPort openstackPort(Port port) {
266 String uuid = port.annotations().value("portName").substring(3);
267 return openstackPortList.stream().filter(p -> p.id().startsWith(uuid))
268 .findAny().orElse(null);
269 }
270
271 /**
272 * Remove flows rules for the removed VM.
273 *
Thomas Vachuska708d3032016-02-18 11:11:46 -0800274 * @param doNotPushFlows true to suppress push of initial flows
Daniel Park5df65182016-01-09 00:12:03 +0900275 * @param removedPort removedport info
276 * @param openstackPortInfoMap openstackPortInfoMap
277 */
sangho3623cb62016-01-15 22:06:38 +0900278 public void removeSwitchingRules(boolean doNotPushFlows, Port removedPort, Map<String,
279 OpenstackPortInfo> openstackPortInfoMap) {
280 if (doNotPushFlows) {
281 return;
282 }
Daniel Park5df65182016-01-09 00:12:03 +0900283 OpenstackPortInfo openstackPortInfo = openstackPortInfoMap
284 .get(removedPort.annotations().value("portName"));
285
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()) {
408 if (!removedPort.annotations().value("portName").equals(entry.getKey())) {
409 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 {
480 extensionInstruction.setPropertyValue("tunnelDst", hostIp);
481 } 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()
sanghoshin46c6e3e2015-12-18 18:42:17 +0900490 .filter(p -> p.annotations().value("portName").equals(
491 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 }
sanghoshin94872a12015-10-16 18:04:34 +0900500}