blob: e944e9ddcb1b336621684df0f7afbbc4eec4daa1 [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;
sanghoshin94872a12015-10-16 18:04:34 +090062
63 private FlowObjectiveService flowObjectiveService;
sanghoshinf25d2e02015-11-11 23:07:17 +090064 private DriverService driverService;
65 private DeviceService deviceService;
sanghoshin94872a12015-10-16 18:04:34 +090066 private ApplicationId appId;
67
sanghoshinf25d2e02015-11-11 23:07:17 +090068 private Collection<OpenstackNetwork> openstackNetworkList;
69 private Collection<OpenstackPort> openstackPortList;
70
sanghoshin94872a12015-10-16 18:04:34 +090071 /**
Ray Milkey87b16b02015-10-30 11:50:00 -070072 * Creates OpenstackSwitchingRulPopulator.
73 *
74 * @param appId application id
sanghoshin94872a12015-10-16 18:04:34 +090075 * @param flowObjectiveService FlowObjectiveService reference
sanghoshinf25d2e02015-11-11 23:07:17 +090076 * @param deviceService DeviceService reference
Hyunsun Moon0dba61f2016-03-03 14:05:21 -080077 * @param openstackService openstack interface service
sanghoshinf25d2e02015-11-11 23:07:17 +090078 * @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,
sangho93447f12016-02-24 00:33:22 +090083 OpenstackInterfaceService 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 *
sanghoshinf25d2e02015-11-11 23:07:17 +090098 * @param device device to populate rules to
99 * @param port port for the VM created
sanghoshin94872a12015-10-16 18:04:34 +0900100 */
sangho93447f12016-02-24 00:33:22 +0900101 public void populateSwitchingRules(Device device, Port port) {
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800102 populateFlowRulesForTunnelTag(device, port);
sanghoshinf25d2e02015-11-11 23:07:17 +0900103 populateFlowRulesForTrafficToSameCnode(device, port);
104 populateFlowRulesForTrafficToDifferentCnode(device, port);
sanghoshin94872a12015-10-16 18:04:34 +0900105 }
106
107 /**
daniel2a2bd7b2015-12-02 13:53:58 +0900108 * Populate the flow rules for tagging tunnelId according to which inport is came from.
109 *
110 * @param device device to put the rules
111 * @param port port info of the VM
112 */
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800113 private void populateFlowRulesForTunnelTag(Device device, Port port) {
daniel2a2bd7b2015-12-02 13:53:58 +0900114 Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName"));
115 String portName = port.annotations().value("portName");
116 String vni = getVniForPort(portName);
117
118 if (vmIp != null) {
Hyunsun Moon74ec4062015-12-09 10:58:32 -0800119 setFlowRuleForTunnelTag(device.id(), port, vni);
daniel2a2bd7b2015-12-02 13:53:58 +0900120 }
121 }
122
Daniel Park5df65182016-01-09 00:12:03 +0900123 private void setFlowRuleForTunnelTag(DeviceId deviceId, Port port, String vni) {
sanghoshin075e3e72015-11-25 16:34:29 +0900124
Daniel Park5df65182016-01-09 00:12:03 +0900125 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
126 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
127
128 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
129 .matchInPort(port.number());
130
131 tBuilder.setTunnelId(Long.parseLong(vni));
132
133 ForwardingObjective fo = DefaultForwardingObjective.builder()
134 .withSelector(sBuilder.build())
135 .withTreatment(tBuilder.build())
136 .withPriority(TUNNELTAG_RULE_PRIORITY)
137 .withFlag(ForwardingObjective.Flag.SPECIFIC)
138 .fromApp(appId)
139 .add();
140
141 flowObjectiveService.forward(deviceId, fo);
sanghoshin65723ae2015-11-17 22:07:21 +0900142 }
143
144 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900145 * Populates the flow rules for traffic to VMs in the same Cnode as the sender.
sanghoshin94872a12015-10-16 18:04:34 +0900146 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900147 * @param device device to put the rules
148 * @param port port info of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900149 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900150 private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) {
151 Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName"));
daniel2a2bd7b2015-12-02 13:53:58 +0900152 String portName = port.annotations().value("portName");
153 String vni = getVniForPort(portName);
daniel2a2bd7b2015-12-02 13:53:58 +0900154
sanghoshinf25d2e02015-11-11 23:07:17 +0900155 if (vmIp != null) {
Daniel Park5df65182016-01-09 00:12:03 +0900156 setFlowRuleForVMsInSameCnode(vmIp, device.id(), port, vni);
sanghoshinf25d2e02015-11-11 23:07:17 +0900157 }
sanghoshin94872a12015-10-16 18:04:34 +0900158 }
159
160 /**
Daniel Park5df65182016-01-09 00:12:03 +0900161 * Sets the flow rules for traffic between VMs in the same Cnode.
162 *
163 * @param ip4Address VM IP address
164 * @param id device ID to put rules
165 * @param port VM port
166 * @param vni VM VNI
167 */
168 private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id,
169 Port port, String vni) {
170
171 //For L2 Switching Case
172 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
173 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
174
175 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
176 .matchIPDst(ip4Address.toIpPrefix())
177 .matchTunnelId(Long.parseLong(vni));
178
179 tBuilder.setOutput(port.number());
180
181 ForwardingObjective fo = DefaultForwardingObjective.builder()
182 .withSelector(sBuilder.build())
183 .withTreatment(tBuilder.build())
184 .withPriority(SWITCHING_RULE_PRIORITY)
185 .withFlag(ForwardingObjective.Flag.SPECIFIC)
186 .fromApp(appId)
187 .add();
188
189 flowObjectiveService.forward(id, fo);
190 }
191
192 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900193 * Populates the flow rules for traffic to VMs in different Cnode using
194 * Nicira extention.
sanghoshin94872a12015-10-16 18:04:34 +0900195 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900196 * @param device device to put rules
197 * @param port port information of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900198 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900199 private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) {
200 String portName = port.annotations().value("portName");
201 String channelId = device.annotations().value("channelId");
202 Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]);
203 Ip4Address fixedIp = getFixedIpAddressForPort(portName);
sanghoshinf25d2e02015-11-11 23:07:17 +0900204 String vni = getVniForPort(portName);
205 deviceService.getAvailableDevices().forEach(d -> {
206 if (!d.equals(device)) {
207 deviceService.getPorts(d.id()).forEach(p -> {
208 String pName = p.annotations().value("portName");
209 if (!p.equals(port) && vni.equals(getVniForPort(pName))) {
210 String cidx = d.annotations().value("channelId");
211 Ip4Address hostIpx = Ip4Address.valueOf(cidx.split(":")[0]);
sanghoshinf25d2e02015-11-11 23:07:17 +0900212 Ip4Address fixedIpx = getFixedIpAddressForPort(pName);
sanghoshin46c6e3e2015-12-18 18:42:17 +0900213 if (port.isEnabled() ||
214 port.annotations().value("portName").startsWith(
215 OpenstackSwitchingManager.PORTNAME_PREFIX_ROUTER)) {
Daniel Park5df65182016-01-09 00:12:03 +0900216 setVxLanFlowRule(vni, device.id(), hostIpx, fixedIpx);
217 setVxLanFlowRule(vni, d.id(), hostIpAddress, fixedIp);
sanghoshin65723ae2015-11-17 22:07:21 +0900218 }
sanghoshinf25d2e02015-11-11 23:07:17 +0900219 }
220 });
221 }
222 });
sanghoshin94872a12015-10-16 18:04:34 +0900223 }
224
225 /**
Daniel Park5df65182016-01-09 00:12:03 +0900226 * Sets the flow rules between traffic from VMs in different Cnode.
227 *
228 * @param vni VNI
229 * @param deviceId device ID
230 * @param hostIp host IP of the VM
231 * @param vmIp fixed IP of the VM
232 */
233 private void setVxLanFlowRule(String vni, DeviceId deviceId, Ip4Address hostIp,
234 Ip4Address vmIp) {
235 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
236 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
237
238 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
239 .matchTunnelId(Long.parseLong(vni))
240 .matchIPDst(vmIp.toIpPrefix());
241 tBuilder.extension(buildNiciraExtenstion(deviceId, hostIp), deviceId)
242 .setOutput(getTunnelPort(deviceId));
243
244 ForwardingObjective fo = DefaultForwardingObjective.builder()
245 .withSelector(sBuilder.build())
246 .withTreatment(tBuilder.build())
247 .withPriority(SWITCHING_RULE_PRIORITY)
248 .withFlag(ForwardingObjective.Flag.SPECIFIC)
249 .fromApp(appId)
250 .add();
251
252 flowObjectiveService.forward(deviceId, fo);
253 }
254
255 /**
256 * Returns OpenstackPort object for the Port reference given.
257 *
258 * @param port Port object
259 * @return OpenstackPort reference, or null when not found
260 */
261 public OpenstackPort openstackPort(Port port) {
262 String uuid = port.annotations().value("portName").substring(3);
263 return openstackPortList.stream().filter(p -> p.id().startsWith(uuid))
264 .findAny().orElse(null);
265 }
266
267 /**
268 * Remove flows rules for the removed VM.
269 *
270 * @param removedPort removedport info
271 * @param openstackPortInfoMap openstackPortInfoMap
272 */
sangho93447f12016-02-24 00:33:22 +0900273 public void removeSwitchingRules(Port removedPort, Map<String,
sangho3623cb62016-01-15 22:06:38 +0900274 OpenstackPortInfo> openstackPortInfoMap) {
Daniel Park5df65182016-01-09 00:12:03 +0900275 OpenstackPortInfo openstackPortInfo = openstackPortInfoMap
276 .get(removedPort.annotations().value("portName"));
277
278 DeviceId deviceId = openstackPortInfo.deviceId();
279 Ip4Address vmIp = openstackPortInfo.ip();
280 PortNumber portNumber = removedPort.number();
281 long vni = openstackPortInfo.vni();
282
283 removeFlowRuleForTunnelTag(deviceId, portNumber);
284 removeFlowRuleForVMsInSameCnode(deviceId, vmIp, vni);
285 removeFlowRuleForVMsInDiffrentCnode(removedPort, deviceId, vmIp, vni, openstackPortInfoMap);
286 }
287
288 /**
289 * Removes flow rules for tagging tunnelId.
290 *
291 * @param deviceId device id
292 * @param portNumber port number
293 */
294 private void removeFlowRuleForTunnelTag(DeviceId deviceId, PortNumber portNumber) {
295 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
296 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
297
298 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
299 .matchInPort(portNumber);
300
301 ForwardingObjective fo = DefaultForwardingObjective.builder()
302 .withSelector(sBuilder.build())
303 .withTreatment(tBuilder.build())
304 .withPriority(TUNNELTAG_RULE_PRIORITY)
305 .withFlag(ForwardingObjective.Flag.SPECIFIC)
306 .fromApp(appId)
307 .remove();
308
309 flowObjectiveService.forward(deviceId, fo);
310 }
311
312 /**
313 * Removes the flow rules for traffic between VMs in the same Cnode.
314 *
315 * @param deviceId device id on which removed VM was run
316 * @param vmIp ip of the removed VM
317 * @param vni vni which removed VM was belonged
318 */
319 private void removeFlowRuleForVMsInSameCnode(DeviceId deviceId, Ip4Address vmIp, long vni) {
320 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
321
322 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
323 .matchIPDst(vmIp.toIpPrefix())
324 .matchTunnelId(vni);
325
326 ForwardingObjective fo = DefaultForwardingObjective.builder()
327 .withSelector(sBuilder.build())
328 .withTreatment(DefaultTrafficTreatment.builder().build())
329 .withFlag(ForwardingObjective.Flag.SPECIFIC)
330 .withPriority(SWITCHING_RULE_PRIORITY)
331 .fromApp(appId)
332 .remove();
333
334 flowObjectiveService.forward(deviceId, fo);
335 }
336
337 /**
338 * Removes the flow rules for traffic between VMs in the different Cnode.
339 *
340 * @param removedPort removedport info
341 * @param deviceId device id on which removed VM was run
342 * @param vmIp ip of the removed VM
343 * @param vni vni which removed VM was belonged
344 * @param openstackPortInfoMap openstackPortInfoMap
345 */
346 private void removeFlowRuleForVMsInDiffrentCnode(Port removedPort, DeviceId deviceId, Ip4Address vmIp,
347 long vni, Map<String, OpenstackPortInfo> openstackPortInfoMap) {
348
349 final boolean anyPortRemainedInSameCnode
350 = checkIfAnyPortRemainedInSameCnode(removedPort, deviceId, vni, openstackPortInfoMap);
351
352 openstackPortInfoMap.forEach((port, portInfo) -> {
353 if (portInfo.vni() == vni && !portInfo.deviceId().equals(deviceId)) {
354 removeVxLanFlowRule(portInfo.deviceId(), vmIp, vni);
355 if (!anyPortRemainedInSameCnode) {
356 removeVxLanFlowRule(deviceId, portInfo.ip(), vni);
357 }
358 }
359 });
360 }
361
362 /**
363 * Removes the flow rules between traffic from VMs in different Cnode.
364 *
365 * @param deviceId device id
366 * @param vmIp ip
367 * @param vni vni which removed VM was belonged
368 */
369 private void removeVxLanFlowRule(DeviceId deviceId, Ip4Address vmIp, long vni) {
370 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
371
372 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
373 .matchTunnelId(vni)
374 .matchIPDst(vmIp.toIpPrefix());
375
376 ForwardingObjective fo = DefaultForwardingObjective.builder()
377 .withSelector(sBuilder.build())
378 .withTreatment(DefaultTrafficTreatment.builder().build())
379 .withFlag(ForwardingObjective.Flag.SPECIFIC)
380 .withPriority(SWITCHING_RULE_PRIORITY)
381 .fromApp(appId)
382 .remove();
383
384 flowObjectiveService.forward(deviceId, fo);
385 }
386
387 /**
388 * Checks if there is any port remained with same vni at the device, on which the removed VM was run.
389 *
390 * @param removedPort removedport info
391 * @param deviceId device id on which removed VM was run
392 * @param vni vni which removed VM was belonged
393 * @param openstackPortInfoMap openstackPortInfoMap
394 * @return true if there is, false otherwise
395 */
396 private boolean checkIfAnyPortRemainedInSameCnode(Port removedPort, DeviceId deviceId, long vni,
397 Map<String, OpenstackPortInfo> openstackPortInfoMap) {
398
399 for (Map.Entry<String, OpenstackPortInfo> entry : openstackPortInfoMap.entrySet()) {
400 if (!removedPort.annotations().value("portName").equals(entry.getKey())) {
401 if (entry.getValue().vni() == vni && entry.getValue().deviceId().equals(deviceId)) {
402 return true;
403 }
404 }
405 }
406 return false;
407 }
408
409 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900410 * Returns the VNI of the VM of the port.
sanghoshin94872a12015-10-16 18:04:34 +0900411 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900412 * @param portName VM port
413 * @return VNI
sanghoshin94872a12015-10-16 18:04:34 +0900414 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900415 private String getVniForPort(String portName) {
416 String uuid = portName.substring(3);
417 OpenstackPort port = openstackPortList.stream()
418 .filter(p -> p.id().startsWith(uuid))
419 .findAny().orElse(null);
420 if (port == null) {
daniel2a2bd7b2015-12-02 13:53:58 +0900421 log.debug("No port information for port {}", portName);
sanghoshinf25d2e02015-11-11 23:07:17 +0900422 return null;
423 }
sanghoshin94872a12015-10-16 18:04:34 +0900424
sanghoshinf25d2e02015-11-11 23:07:17 +0900425 OpenstackNetwork network = openstackNetworkList.stream()
426 .filter(n -> n.id().equals(port.networkId()))
427 .findAny().orElse(null);
428 if (network == null) {
Satish K2e2d6352015-11-27 12:02:15 +0530429 log.warn("No VNI information for network {}", port.networkId());
sanghoshinf25d2e02015-11-11 23:07:17 +0900430 return null;
431 }
sanghoshin94872a12015-10-16 18:04:34 +0900432
sanghoshinf25d2e02015-11-11 23:07:17 +0900433 return network.segmentId();
sanghoshin94872a12015-10-16 18:04:34 +0900434 }
435
436 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900437 * Returns the Fixed IP address of the VM.
sanghoshin94872a12015-10-16 18:04:34 +0900438 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900439 * @param portName VM port info
440 * @return IP address of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900441 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900442 private Ip4Address getFixedIpAddressForPort(String portName) {
sanghoshin94872a12015-10-16 18:04:34 +0900443
sanghoshinf25d2e02015-11-11 23:07:17 +0900444 String uuid = portName.substring(3);
445 OpenstackPort port = openstackPortList.stream()
446 .filter(p -> p.id().startsWith(uuid))
447 .findFirst().orElse(null);
sanghoshin94872a12015-10-16 18:04:34 +0900448
sanghoshinf25d2e02015-11-11 23:07:17 +0900449 if (port == null) {
450 log.error("There is no port information for port name {}", portName);
451 return null;
452 }
sanghoshin94872a12015-10-16 18:04:34 +0900453
sanghoshinf25d2e02015-11-11 23:07:17 +0900454 if (port.fixedIps().isEmpty()) {
455 log.error("There is no fixed IP info in the port information");
456 return null;
457 }
458
459 return (Ip4Address) port.fixedIps().values().toArray()[0];
460 }
461
sanghoshinf25d2e02015-11-11 23:07:17 +0900462 private ExtensionTreatment buildNiciraExtenstion(DeviceId id, Ip4Address hostIp) {
463 Driver driver = driverService.getDriver(id);
464 DriverHandler driverHandler = new DefaultDriverHandler(new DefaultDriverData(driver, id));
465 ExtensionTreatmentResolver resolver = driverHandler.behaviour(ExtensionTreatmentResolver.class);
466
467 ExtensionTreatment extensionInstruction =
468 resolver.getExtensionInstruction(
469 ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type());
470
471 try {
472 extensionInstruction.setPropertyValue("tunnelDst", hostIp);
473 } catch (ExtensionPropertyException e) {
474 log.error("Error setting Nicira extension setting {}", e);
475 }
476
477 return extensionInstruction;
478 }
479
Daniel Park5df65182016-01-09 00:12:03 +0900480 private PortNumber getTunnelPort(DeviceId deviceId) {
481 Port port = deviceService.getPorts(deviceId).stream()
sanghoshin46c6e3e2015-12-18 18:42:17 +0900482 .filter(p -> p.annotations().value("portName").equals(
483 OpenstackSwitchingManager.PORTNAME_PREFIX_TUNNEL))
sanghoshinf25d2e02015-11-11 23:07:17 +0900484 .findAny().orElse(null);
485
486 if (port == null) {
487 log.error("No TunnelPort was created.");
488 return null;
489 }
490 return port.number();
491 }
sangho90088532016-02-25 18:06:12 +0900492
sanghoshin94872a12015-10-16 18:04:34 +0900493}