blob: cc94c93d6759aa2441501d089f2368298ec995ef [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
Jian Li7f256f52016-01-24 15:08:05 -080017package org.onosproject.openstackswitching.impl;
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;
Jian Li7f256f52016-01-24 15:08:05 -080043import org.onosproject.openstackswitching.OpenstackNetwork;
44import org.onosproject.openstackswitching.OpenstackPort;
sanghoshin94872a12015-10-16 18:04:34 +090045import org.slf4j.Logger;
46import org.slf4j.LoggerFactory;
47
sanghoshinf25d2e02015-11-11 23:07:17 +090048import java.util.Collection;
Daniel Park5df65182016-01-09 00:12:03 +090049import java.util.Map;
sanghoshinf25d2e02015-11-11 23:07:17 +090050
sanghoshin94872a12015-10-16 18:04:34 +090051/**
sanghoshin46297d22015-11-03 17:51:24 +090052 * Populates switching flow rules.
sanghoshin94872a12015-10-16 18:04:34 +090053 */
54public class OpenstackSwitchingRulePopulator {
55
56 private static Logger log = LoggerFactory
57 .getLogger(OpenstackSwitchingRulePopulator.class);
daniel2a2bd7b2015-12-02 13:53:58 +090058 private static final int SWITCHING_RULE_PRIORITY = 30000;
59 private static final int EAST_WEST_ROUTING_RULE_PRIORITY = 29000;
60 private static final int TUNNELTAG_RULE_PRIORITY = 30000;
sanghoshin94872a12015-10-16 18:04:34 +090061
62 private FlowObjectiveService flowObjectiveService;
sanghoshinf25d2e02015-11-11 23:07:17 +090063 private DriverService driverService;
64 private DeviceService deviceService;
65 private OpenstackRestHandler restHandler;
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
Jian Lidfba7392016-01-22 16:46:58 -080077 * @param restHandler OpenstackRestHandler reference
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,
83 OpenstackRestHandler restHandler,
84 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;
88 this.restHandler = restHandler;
sanghoshin94872a12015-10-16 18:04:34 +090089 this.appId = appId;
sanghoshinf25d2e02015-11-11 23:07:17 +090090
91 openstackNetworkList = restHandler.getNetworks();
92 openstackPortList = restHandler.getPorts();
sanghoshin94872a12015-10-16 18:04:34 +090093 }
94
daniel2a2bd7b2015-12-02 13:53:58 +090095
sanghoshin94872a12015-10-16 18:04:34 +090096 /**
sanghoshinf25d2e02015-11-11 23:07:17 +090097 * Populates flow rules for the VM created.
sanghoshin94872a12015-10-16 18:04:34 +090098 *
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 *
274 * @param removedPort removedport info
275 * @param openstackPortInfoMap openstackPortInfoMap
276 */
sangho3623cb62016-01-15 22:06:38 +0900277 public void removeSwitchingRules(boolean doNotPushFlows, Port removedPort, Map<String,
278 OpenstackPortInfo> openstackPortInfoMap) {
279 if (doNotPushFlows) {
280 return;
281 }
Daniel Park5df65182016-01-09 00:12:03 +0900282 OpenstackPortInfo openstackPortInfo = openstackPortInfoMap
283 .get(removedPort.annotations().value("portName"));
284
285 DeviceId deviceId = openstackPortInfo.deviceId();
286 Ip4Address vmIp = openstackPortInfo.ip();
287 PortNumber portNumber = removedPort.number();
288 long vni = openstackPortInfo.vni();
289
290 removeFlowRuleForTunnelTag(deviceId, portNumber);
291 removeFlowRuleForVMsInSameCnode(deviceId, vmIp, vni);
292 removeFlowRuleForVMsInDiffrentCnode(removedPort, deviceId, vmIp, vni, openstackPortInfoMap);
293 }
294
295 /**
296 * Removes flow rules for tagging tunnelId.
297 *
298 * @param deviceId device id
299 * @param portNumber port number
300 */
301 private void removeFlowRuleForTunnelTag(DeviceId deviceId, PortNumber portNumber) {
302 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
303 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
304
305 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
306 .matchInPort(portNumber);
307
308 ForwardingObjective fo = DefaultForwardingObjective.builder()
309 .withSelector(sBuilder.build())
310 .withTreatment(tBuilder.build())
311 .withPriority(TUNNELTAG_RULE_PRIORITY)
312 .withFlag(ForwardingObjective.Flag.SPECIFIC)
313 .fromApp(appId)
314 .remove();
315
316 flowObjectiveService.forward(deviceId, fo);
317 }
318
319 /**
320 * Removes the flow rules for traffic between VMs in the same Cnode.
321 *
322 * @param deviceId device id on which removed VM was run
323 * @param vmIp ip of the removed VM
324 * @param vni vni which removed VM was belonged
325 */
326 private void removeFlowRuleForVMsInSameCnode(DeviceId deviceId, Ip4Address vmIp, long vni) {
327 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
328
329 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
330 .matchIPDst(vmIp.toIpPrefix())
331 .matchTunnelId(vni);
332
333 ForwardingObjective fo = DefaultForwardingObjective.builder()
334 .withSelector(sBuilder.build())
335 .withTreatment(DefaultTrafficTreatment.builder().build())
336 .withFlag(ForwardingObjective.Flag.SPECIFIC)
337 .withPriority(SWITCHING_RULE_PRIORITY)
338 .fromApp(appId)
339 .remove();
340
341 flowObjectiveService.forward(deviceId, fo);
342 }
343
344 /**
345 * Removes the flow rules for traffic between VMs in the different Cnode.
346 *
347 * @param removedPort removedport info
348 * @param deviceId device id on which removed VM was run
349 * @param vmIp ip of the removed VM
350 * @param vni vni which removed VM was belonged
351 * @param openstackPortInfoMap openstackPortInfoMap
352 */
353 private void removeFlowRuleForVMsInDiffrentCnode(Port removedPort, DeviceId deviceId, Ip4Address vmIp,
354 long vni, Map<String, OpenstackPortInfo> openstackPortInfoMap) {
355
356 final boolean anyPortRemainedInSameCnode
357 = checkIfAnyPortRemainedInSameCnode(removedPort, deviceId, vni, openstackPortInfoMap);
358
359 openstackPortInfoMap.forEach((port, portInfo) -> {
360 if (portInfo.vni() == vni && !portInfo.deviceId().equals(deviceId)) {
361 removeVxLanFlowRule(portInfo.deviceId(), vmIp, vni);
362 if (!anyPortRemainedInSameCnode) {
363 removeVxLanFlowRule(deviceId, portInfo.ip(), vni);
364 }
365 }
366 });
367 }
368
369 /**
370 * Removes the flow rules between traffic from VMs in different Cnode.
371 *
372 * @param deviceId device id
373 * @param vmIp ip
374 * @param vni vni which removed VM was belonged
375 */
376 private void removeVxLanFlowRule(DeviceId deviceId, Ip4Address vmIp, long vni) {
377 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
378
379 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
380 .matchTunnelId(vni)
381 .matchIPDst(vmIp.toIpPrefix());
382
383 ForwardingObjective fo = DefaultForwardingObjective.builder()
384 .withSelector(sBuilder.build())
385 .withTreatment(DefaultTrafficTreatment.builder().build())
386 .withFlag(ForwardingObjective.Flag.SPECIFIC)
387 .withPriority(SWITCHING_RULE_PRIORITY)
388 .fromApp(appId)
389 .remove();
390
391 flowObjectiveService.forward(deviceId, fo);
392 }
393
394 /**
395 * Checks if there is any port remained with same vni at the device, on which the removed VM was run.
396 *
397 * @param removedPort removedport info
398 * @param deviceId device id on which removed VM was run
399 * @param vni vni which removed VM was belonged
400 * @param openstackPortInfoMap openstackPortInfoMap
401 * @return true if there is, false otherwise
402 */
403 private boolean checkIfAnyPortRemainedInSameCnode(Port removedPort, DeviceId deviceId, long vni,
404 Map<String, OpenstackPortInfo> openstackPortInfoMap) {
405
406 for (Map.Entry<String, OpenstackPortInfo> entry : openstackPortInfoMap.entrySet()) {
407 if (!removedPort.annotations().value("portName").equals(entry.getKey())) {
408 if (entry.getValue().vni() == vni && entry.getValue().deviceId().equals(deviceId)) {
409 return true;
410 }
411 }
412 }
413 return false;
414 }
415
416 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900417 * Returns the VNI of the VM of the port.
sanghoshin94872a12015-10-16 18:04:34 +0900418 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900419 * @param portName VM port
420 * @return VNI
sanghoshin94872a12015-10-16 18:04:34 +0900421 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900422 private String getVniForPort(String portName) {
423 String uuid = portName.substring(3);
424 OpenstackPort port = openstackPortList.stream()
425 .filter(p -> p.id().startsWith(uuid))
426 .findAny().orElse(null);
427 if (port == null) {
daniel2a2bd7b2015-12-02 13:53:58 +0900428 log.debug("No port information for port {}", portName);
sanghoshinf25d2e02015-11-11 23:07:17 +0900429 return null;
430 }
sanghoshin94872a12015-10-16 18:04:34 +0900431
sanghoshinf25d2e02015-11-11 23:07:17 +0900432 OpenstackNetwork network = openstackNetworkList.stream()
433 .filter(n -> n.id().equals(port.networkId()))
434 .findAny().orElse(null);
435 if (network == null) {
Satish K2e2d6352015-11-27 12:02:15 +0530436 log.warn("No VNI information for network {}", port.networkId());
sanghoshinf25d2e02015-11-11 23:07:17 +0900437 return null;
438 }
sanghoshin94872a12015-10-16 18:04:34 +0900439
sanghoshinf25d2e02015-11-11 23:07:17 +0900440 return network.segmentId();
sanghoshin94872a12015-10-16 18:04:34 +0900441 }
442
443 /**
sanghoshinf25d2e02015-11-11 23:07:17 +0900444 * Returns the Fixed IP address of the VM.
sanghoshin94872a12015-10-16 18:04:34 +0900445 *
sanghoshinf25d2e02015-11-11 23:07:17 +0900446 * @param portName VM port info
447 * @return IP address of the VM
sanghoshin94872a12015-10-16 18:04:34 +0900448 */
sanghoshinf25d2e02015-11-11 23:07:17 +0900449 private Ip4Address getFixedIpAddressForPort(String portName) {
sanghoshin94872a12015-10-16 18:04:34 +0900450
sanghoshinf25d2e02015-11-11 23:07:17 +0900451 String uuid = portName.substring(3);
452 OpenstackPort port = openstackPortList.stream()
453 .filter(p -> p.id().startsWith(uuid))
454 .findFirst().orElse(null);
sanghoshin94872a12015-10-16 18:04:34 +0900455
sanghoshinf25d2e02015-11-11 23:07:17 +0900456 if (port == null) {
457 log.error("There is no port information for port name {}", portName);
458 return null;
459 }
sanghoshin94872a12015-10-16 18:04:34 +0900460
sanghoshinf25d2e02015-11-11 23:07:17 +0900461 if (port.fixedIps().isEmpty()) {
462 log.error("There is no fixed IP info in the port information");
463 return null;
464 }
465
466 return (Ip4Address) port.fixedIps().values().toArray()[0];
467 }
468
sanghoshinf25d2e02015-11-11 23:07:17 +0900469 private ExtensionTreatment buildNiciraExtenstion(DeviceId id, Ip4Address hostIp) {
470 Driver driver = driverService.getDriver(id);
471 DriverHandler driverHandler = new DefaultDriverHandler(new DefaultDriverData(driver, id));
472 ExtensionTreatmentResolver resolver = driverHandler.behaviour(ExtensionTreatmentResolver.class);
473
474 ExtensionTreatment extensionInstruction =
475 resolver.getExtensionInstruction(
476 ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type());
477
478 try {
479 extensionInstruction.setPropertyValue("tunnelDst", hostIp);
480 } catch (ExtensionPropertyException e) {
481 log.error("Error setting Nicira extension setting {}", e);
482 }
483
484 return extensionInstruction;
485 }
486
Daniel Park5df65182016-01-09 00:12:03 +0900487 private PortNumber getTunnelPort(DeviceId deviceId) {
488 Port port = deviceService.getPorts(deviceId).stream()
sanghoshin46c6e3e2015-12-18 18:42:17 +0900489 .filter(p -> p.annotations().value("portName").equals(
490 OpenstackSwitchingManager.PORTNAME_PREFIX_TUNNEL))
sanghoshinf25d2e02015-11-11 23:07:17 +0900491 .findAny().orElse(null);
492
493 if (port == null) {
494 log.error("No TunnelPort was created.");
495 return null;
496 }
497 return port.number();
498 }
sanghoshin94872a12015-10-16 18:04:34 +0900499}