blob: 4e01d2ba9a17eba8eb9d2bfb1ee25fb086ac66da [file] [log] [blame]
Hyunsun Moone7e4bb32016-05-16 04:32:45 -07001/*
2 * Copyright 2016-present 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 */
alshabibb4d31712016-06-01 18:51:03 -070016package org.opencord.cordvtn.impl;
Hyunsun Moone7e4bb32016-05-16 04:32:45 -070017
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
24import org.onlab.packet.Ethernet;
25import org.onlab.packet.IPv4;
26import org.onlab.packet.Ip4Address;
27import org.onlab.packet.IpAddress;
28import org.onlab.packet.TpPort;
29import org.onlab.packet.VlanId;
Hyunsun Moonc031d9b2016-08-04 13:57:22 -070030import org.onosproject.net.AnnotationKeys;
31import org.onosproject.net.Port;
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070032import org.opencord.cordvtn.api.Constants;
alshabibb4d31712016-06-01 18:51:03 -070033import org.opencord.cordvtn.api.CordVtnNode;
Hyunsun Moone7e4bb32016-05-16 04:32:45 -070034import org.onosproject.core.ApplicationId;
35import org.onosproject.core.CoreService;
36import org.onosproject.net.Device;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.PortNumber;
39import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
40import org.onosproject.net.device.DeviceService;
41import org.onosproject.net.flow.DefaultFlowRule;
42import org.onosproject.net.flow.DefaultTrafficSelector;
43import org.onosproject.net.flow.DefaultTrafficTreatment;
44import org.onosproject.net.flow.FlowRule;
45import org.onosproject.net.flow.FlowRuleOperations;
46import org.onosproject.net.flow.FlowRuleOperationsContext;
47import org.onosproject.net.flow.FlowRuleService;
48import org.onosproject.net.flow.TrafficSelector;
49import org.onosproject.net.flow.TrafficTreatment;
50import org.onosproject.net.flow.instructions.ExtensionPropertyException;
51import org.onosproject.net.flow.instructions.ExtensionTreatment;
52import org.slf4j.Logger;
53
Hyunsun Moonc031d9b2016-08-04 13:57:22 -070054import java.util.Optional;
55
Hyunsun Moone7e4bb32016-05-16 04:32:45 -070056import static com.google.common.base.Preconditions.checkNotNull;
57import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
Hyunsun Moonc031d9b2016-08-04 13:57:22 -070058import static org.opencord.cordvtn.api.Constants.DEFAULT_TUNNEL;
Hyunsun Moone7e4bb32016-05-16 04:32:45 -070059import static org.slf4j.LoggerFactory.getLogger;
60
61/**
62 * Provides CORD VTN pipeline.
63 */
64@Component(immediate = true)
65@Service(value = CordVtnPipeline.class)
66public final class CordVtnPipeline {
67
68 protected final Logger log = getLogger(getClass());
69
70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected CoreService coreService;
72
73 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
74 protected FlowRuleService flowRuleService;
75
76 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
77 protected DeviceService deviceService;
78
79 // tables
80 public static final int TABLE_ZERO = 0;
81 public static final int TABLE_IN_PORT = 1;
Hyunsun Moonfb417942016-06-23 14:48:20 -070082 public static final int TABLE_ACCESS_TYPE = 2;
Hyunsun Moone7e4bb32016-05-16 04:32:45 -070083 public static final int TABLE_IN_SERVICE = 3;
Hyunsun Moonfb417942016-06-23 14:48:20 -070084 public static final int TABLE_DST_IP = 4;
Hyunsun Moone7e4bb32016-05-16 04:32:45 -070085 public static final int TABLE_TUNNEL_IN = 5;
86 public static final int TABLE_VLAN = 6;
87
88 // priorities
89 public static final int PRIORITY_MANAGEMENT = 55000;
90 public static final int PRIORITY_HIGH = 50000;
91 public static final int PRIORITY_DEFAULT = 5000;
92 public static final int PRIORITY_LOW = 4000;
93 public static final int PRIORITY_ZERO = 0;
94
95 public static final int VXLAN_UDP_PORT = 4789;
96 public static final VlanId VLAN_WAN = VlanId.vlanId((short) 500);
Hyunsun Moone7e4bb32016-05-16 04:32:45 -070097
Hyunsun Moonc031d9b2016-08-04 13:57:22 -070098 public static final String PROPERTY_TUNNEL_DST = "tunnelDst";
99
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700100 private ApplicationId appId;
101
102 @Activate
103 protected void activate() {
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700104 appId = coreService.registerApplication(Constants.CORDVTN_APP_ID);
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700105 log.info("Started");
106 }
107
108 @Deactivate
109 protected void deactivate() {
110 log.info("Stopped");
111 }
112
113 /**
114 * Flush flows installed by this application.
115 */
116 public void flushRules() {
117 flowRuleService.getFlowRulesById(appId).forEach(flowRule -> processFlowRule(false, flowRule));
118 }
119
120 /**
121 * Installs table miss rule to a give device.
122 *
123 * @param node cordvtn node
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700124 */
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700125 public void initPipeline(CordVtnNode node) {
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700126 checkNotNull(node);
127
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700128 Optional<PortNumber> dataPort = getPortNumber(node.integrationBridgeId(), node.dataIface());
129 Optional<PortNumber> tunnelPort = getPortNumber(node.integrationBridgeId(), DEFAULT_TUNNEL);
130 if (!dataPort.isPresent() || !tunnelPort.isPresent()) {
131 log.warn("Node is not in COMPLETE state");
132 return;
133 }
134
135 Optional<PortNumber> hostMgmtPort = Optional.empty();
136 if (node.hostMgmtIface().isPresent()) {
137 hostMgmtPort = getPortNumber(node.integrationBridgeId(), node.hostMgmtIface().get());
138 }
139
140 processTableZero(node.integrationBridgeId(),
141 dataPort.get(),
142 node.dataIp().ip(),
143 node.localMgmtIp().ip());
144
145 processInPortTable(node.integrationBridgeId(),
146 tunnelPort.get(),
147 dataPort.get(),
148 hostMgmtPort);
149
150 processAccessTypeTable(node.integrationBridgeId(), dataPort.get());
151 processVlanTable(node.integrationBridgeId(), dataPort.get());
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700152 }
153
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700154 private void processTableZero(DeviceId deviceId, PortNumber dataPort, IpAddress dataIp,
155 IpAddress localMgmtIp) {
156 vxlanShuttleRule(deviceId, dataPort, dataIp);
157 localManagementBaseRule(deviceId, localMgmtIp.getIp4Address());
158
159 // take all vlan tagged packet to the VLAN table
160 TrafficSelector selector = DefaultTrafficSelector.builder()
161 .matchVlanId(VlanId.ANY)
162 .build();
163
164 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
165 .transition(TABLE_VLAN)
166 .build();
167
168 FlowRule flowRule = DefaultFlowRule.builder()
169 .fromApp(appId)
170 .withSelector(selector)
171 .withTreatment(treatment)
172 .withPriority(PRIORITY_MANAGEMENT)
173 .forDevice(deviceId)
174 .forTable(TABLE_ZERO)
175 .makePermanent()
176 .build();
177
178 processFlowRule(true, flowRule);
179
180 // take all other packets to the next table
181 selector = DefaultTrafficSelector.builder()
182 .build();
183
184 treatment = DefaultTrafficTreatment.builder()
185 .transition(TABLE_IN_PORT)
186 .build();
187
188 flowRule = DefaultFlowRule.builder()
189 .fromApp(appId)
190 .withSelector(selector)
191 .withTreatment(treatment)
192 .withPriority(PRIORITY_ZERO)
193 .forDevice(deviceId)
194 .forTable(TABLE_ZERO)
195 .makePermanent()
196 .build();
197
198 processFlowRule(true, flowRule);
199 }
200
201 private void vxlanShuttleRule(DeviceId deviceId, PortNumber dataPort, IpAddress dataIp) {
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700202 // take vxlan packet out onto the physical port
203 TrafficSelector selector = DefaultTrafficSelector.builder()
204 .matchInPort(PortNumber.LOCAL)
205 .build();
206
207 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Hyunsun Moon81a13562016-08-04 13:48:08 -0700208 .setOutput(dataPort)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700209 .build();
210
211 FlowRule flowRule = DefaultFlowRule.builder()
212 .fromApp(appId)
213 .withSelector(selector)
214 .withTreatment(treatment)
215 .withPriority(PRIORITY_HIGH)
216 .forDevice(deviceId)
217 .forTable(TABLE_ZERO)
218 .makePermanent()
219 .build();
220
221 processFlowRule(true, flowRule);
222
223 // take a vxlan encap'd packet through the Linux stack
224 selector = DefaultTrafficSelector.builder()
Hyunsun Moon81a13562016-08-04 13:48:08 -0700225 .matchInPort(dataPort)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700226 .matchEthType(Ethernet.TYPE_IPV4)
227 .matchIPProtocol(IPv4.PROTOCOL_UDP)
228 .matchUdpDst(TpPort.tpPort(VXLAN_UDP_PORT))
229 .build();
230
231 treatment = DefaultTrafficTreatment.builder()
232 .setOutput(PortNumber.LOCAL)
233 .build();
234
235 flowRule = DefaultFlowRule.builder()
236 .fromApp(appId)
237 .withSelector(selector)
238 .withTreatment(treatment)
239 .withPriority(PRIORITY_HIGH)
240 .forDevice(deviceId)
241 .forTable(TABLE_ZERO)
242 .makePermanent()
243 .build();
244
245 processFlowRule(true, flowRule);
246
247 // take a packet to the data plane ip through Linux stack
248 selector = DefaultTrafficSelector.builder()
Hyunsun Moon81a13562016-08-04 13:48:08 -0700249 .matchInPort(dataPort)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700250 .matchEthType(Ethernet.TYPE_IPV4)
Hyunsun Moon81a13562016-08-04 13:48:08 -0700251 .matchIPDst(dataIp.toIpPrefix())
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700252 .build();
253
254 treatment = DefaultTrafficTreatment.builder()
255 .setOutput(PortNumber.LOCAL)
256 .build();
257
258 flowRule = DefaultFlowRule.builder()
259 .fromApp(appId)
260 .withSelector(selector)
261 .withTreatment(treatment)
262 .withPriority(PRIORITY_HIGH)
263 .forDevice(deviceId)
264 .forTable(TABLE_ZERO)
265 .makePermanent()
266 .build();
267
268 processFlowRule(true, flowRule);
269
270 // take an arp packet from physical through Linux stack
271 selector = DefaultTrafficSelector.builder()
Hyunsun Moon81a13562016-08-04 13:48:08 -0700272 .matchInPort(dataPort)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700273 .matchEthType(Ethernet.TYPE_ARP)
Hyunsun Moon81a13562016-08-04 13:48:08 -0700274 .matchArpTpa(dataIp.getIp4Address())
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700275 .build();
276
277 treatment = DefaultTrafficTreatment.builder()
278 .setOutput(PortNumber.LOCAL)
279 .build();
280
281 flowRule = DefaultFlowRule.builder()
282 .fromApp(appId)
283 .withSelector(selector)
284 .withTreatment(treatment)
285 .withPriority(PRIORITY_HIGH)
286 .forDevice(deviceId)
287 .forTable(TABLE_ZERO)
288 .makePermanent()
289 .build();
290
291 processFlowRule(true, flowRule);
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700292 }
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700293
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700294 private void localManagementBaseRule(DeviceId deviceId, Ip4Address localMgmtIp) {
295 TrafficSelector selector = DefaultTrafficSelector.builder()
296 .matchEthType(Ethernet.TYPE_ARP)
297 .matchArpTpa(localMgmtIp)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700298 .build();
299
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700300 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
301 .setOutput(PortNumber.LOCAL)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700302 .build();
303
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700304 FlowRule flowRule = DefaultFlowRule.builder()
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700305 .fromApp(appId)
306 .withSelector(selector)
307 .withTreatment(treatment)
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700308 .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700309 .forDevice(deviceId)
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700310 .forTable(CordVtnPipeline.TABLE_ZERO)
Hyunsun Moonacbc8ef2016-06-21 17:58:45 -0700311 .makePermanent()
312 .build();
313
314 processFlowRule(true, flowRule);
315
316 selector = DefaultTrafficSelector.builder()
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700317 .matchInPort(PortNumber.LOCAL)
318 .matchEthType(Ethernet.TYPE_IPV4)
319 .matchIPSrc(localMgmtIp.toIpPrefix())
Hyunsun Moonacbc8ef2016-06-21 17:58:45 -0700320 .build();
321
322 treatment = DefaultTrafficTreatment.builder()
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700323 .transition(CordVtnPipeline.TABLE_DST_IP)
Hyunsun Moonacbc8ef2016-06-21 17:58:45 -0700324 .build();
325
326 flowRule = DefaultFlowRule.builder()
327 .fromApp(appId)
328 .withSelector(selector)
329 .withTreatment(treatment)
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700330 .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
Hyunsun Moonacbc8ef2016-06-21 17:58:45 -0700331 .forDevice(deviceId)
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700332 .forTable(CordVtnPipeline.TABLE_ZERO)
333 .makePermanent()
334 .build();
335
336 processFlowRule(true, flowRule);
337
338 selector = DefaultTrafficSelector.builder()
339 .matchEthType(Ethernet.TYPE_IPV4)
340 .matchIPDst(localMgmtIp.toIpPrefix())
341 .build();
342
343 treatment = DefaultTrafficTreatment.builder()
344 .setOutput(PortNumber.LOCAL)
345 .build();
346
347 flowRule = DefaultFlowRule.builder()
348 .fromApp(appId)
349 .withSelector(selector)
350 .withTreatment(treatment)
351 .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
352 .forDevice(deviceId)
353 .forTable(CordVtnPipeline.TABLE_ZERO)
354 .makePermanent()
355 .build();
356
357 processFlowRule(true, flowRule);
358
359 selector = DefaultTrafficSelector.builder()
360 .matchInPort(PortNumber.LOCAL)
361 .matchEthType(Ethernet.TYPE_ARP)
362 .matchArpSpa(localMgmtIp)
363 .build();
364
365 treatment = DefaultTrafficTreatment.builder()
366 .setOutput(PortNumber.CONTROLLER)
367 .build();
368
369 flowRule = DefaultFlowRule.builder()
370 .fromApp(appId)
371 .withSelector(selector)
372 .withTreatment(treatment)
373 .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
374 .forDevice(deviceId)
375 .forTable(CordVtnPipeline.TABLE_ZERO)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700376 .makePermanent()
377 .build();
378
379 processFlowRule(true, flowRule);
380 }
381
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700382 private void processInPortTable(DeviceId deviceId, PortNumber tunnelPort, PortNumber dataPort,
383 Optional<PortNumber> hostMgmtPort) {
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700384 TrafficSelector selector = DefaultTrafficSelector.builder()
385 .matchInPort(tunnelPort)
386 .build();
387
388 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
389 .transition(TABLE_TUNNEL_IN)
390 .build();
391
392 FlowRule flowRule = DefaultFlowRule.builder()
393 .fromApp(appId)
394 .withSelector(selector)
395 .withTreatment(treatment)
396 .withPriority(PRIORITY_DEFAULT)
397 .forDevice(deviceId)
398 .forTable(TABLE_IN_PORT)
399 .makePermanent()
400 .build();
401
402 processFlowRule(true, flowRule);
403
404 selector = DefaultTrafficSelector.builder()
Hyunsun Moon81a13562016-08-04 13:48:08 -0700405 .matchInPort(dataPort)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700406 .build();
407
408 treatment = DefaultTrafficTreatment.builder()
Hyunsun Moonfb417942016-06-23 14:48:20 -0700409 .transition(TABLE_DST_IP)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700410 .build();
411
412 flowRule = DefaultFlowRule.builder()
413 .fromApp(appId)
414 .withSelector(selector)
415 .withTreatment(treatment)
416 .withPriority(PRIORITY_DEFAULT)
417 .forDevice(deviceId)
418 .forTable(TABLE_IN_PORT)
419 .makePermanent()
420 .build();
421
422 processFlowRule(true, flowRule);
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700423
424 if (hostMgmtPort.isPresent()) {
425 selector = DefaultTrafficSelector.builder()
426 .matchInPort(hostMgmtPort.get())
427 .build();
428
429 treatment = DefaultTrafficTreatment.builder()
430 .transition(TABLE_DST_IP)
431 .build();
432
433 flowRule = DefaultFlowRule.builder()
434 .fromApp(appId)
435 .withSelector(selector)
436 .withTreatment(treatment)
437 .withPriority(PRIORITY_DEFAULT)
438 .forDevice(deviceId)
439 .forTable(TABLE_IN_PORT)
440 .makePermanent()
441 .build();
442
443 processFlowRule(true, flowRule);
444 }
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700445 }
446
Hyunsun Moon81a13562016-08-04 13:48:08 -0700447 private void processAccessTypeTable(DeviceId deviceId, PortNumber dataPort) {
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700448 TrafficSelector selector = DefaultTrafficSelector.builder()
449 .build();
450
451 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Hyunsun Moon81a13562016-08-04 13:48:08 -0700452 .setOutput(dataPort)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700453 .build();
454
455 FlowRule flowRule = DefaultFlowRule.builder()
456 .fromApp(appId)
457 .withSelector(selector)
458 .withTreatment(treatment)
459 .withPriority(PRIORITY_ZERO)
460 .forDevice(deviceId)
Hyunsun Moonfb417942016-06-23 14:48:20 -0700461 .forTable(TABLE_ACCESS_TYPE)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700462 .makePermanent()
463 .build();
464
465 processFlowRule(true, flowRule);
466 }
467
Hyunsun Moon81a13562016-08-04 13:48:08 -0700468 private void processVlanTable(DeviceId deviceId, PortNumber dataPort) {
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700469 // for traffic going out to WAN, strip vid 500 and take through data plane interface
470 TrafficSelector selector = DefaultTrafficSelector.builder()
471 .matchVlanId(VLAN_WAN)
472 .build();
473
474 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
475 .popVlan()
Hyunsun Moon81a13562016-08-04 13:48:08 -0700476 .setOutput(dataPort)
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700477 .build();
478
479 FlowRule flowRule = DefaultFlowRule.builder()
480 .fromApp(appId)
481 .withSelector(selector)
482 .withTreatment(treatment)
483 .withPriority(PRIORITY_DEFAULT)
484 .forDevice(deviceId)
485 .forTable(TABLE_VLAN)
486 .makePermanent()
487 .build();
488
489 processFlowRule(true, flowRule);
490
491 selector = DefaultTrafficSelector.builder()
492 .matchVlanId(VLAN_WAN)
493 .matchEthType(Ethernet.TYPE_ARP)
494 .build();
495
496 treatment = DefaultTrafficTreatment.builder()
497 .setOutput(PortNumber.CONTROLLER)
498 .build();
499
500 flowRule = DefaultFlowRule.builder()
501 .fromApp(appId)
502 .withSelector(selector)
503 .withTreatment(treatment)
504 .withPriority(PRIORITY_HIGH)
505 .forDevice(deviceId)
506 .forTable(TABLE_VLAN)
507 .makePermanent()
508 .build();
509
510 processFlowRule(true, flowRule);
511 }
512
513 public void processFlowRule(boolean install, FlowRule rule) {
514 FlowRuleOperations.Builder oBuilder = FlowRuleOperations.builder();
515 oBuilder = install ? oBuilder.add(rule) : oBuilder.remove(rule);
516
517 flowRuleService.apply(oBuilder.build(new FlowRuleOperationsContext() {
518 @Override
519 public void onError(FlowRuleOperations ops) {
520 log.error(String.format("Failed %s, %s", ops.toString(), rule.toString()));
521 }
522 }));
523 }
524
525 public ExtensionTreatment tunnelDstTreatment(DeviceId deviceId, Ip4Address remoteIp) {
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700526 Device device = deviceService.getDevice(deviceId);
527 if (device != null && !device.is(ExtensionTreatmentResolver.class)) {
528 log.error("The extension treatment is not supported");
Hyunsun Moonacbc8ef2016-06-21 17:58:45 -0700529 return null;
530 }
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700531
532 ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
533 ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
534 try {
535 treatment.setPropertyValue(PROPERTY_TUNNEL_DST, remoteIp);
536 return treatment;
537 } catch (ExtensionPropertyException e) {
538 log.warn("Failed to get tunnelDst extension treatment for {}", deviceId);
539 return null;
540 }
541 }
542
543 private Optional<PortNumber> getPortNumber(DeviceId deviceId, String portName) {
544 PortNumber port = deviceService.getPorts(deviceId).stream()
545 .filter(p -> p.annotations().value(AnnotationKeys.PORT_NAME).equals(portName) &&
546 p.isEnabled())
547 .map(Port::number)
548 .findAny()
549 .orElse(null);
550 return Optional.ofNullable(port);
Hyunsun Moonacbc8ef2016-06-21 17:58:45 -0700551 }
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700552}