blob: 3c76e89f4f1d1d905297b6c91248d7d11159ee69 [file] [log] [blame]
Phaneendra Manda8db7d092016-06-04 00:17:24 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Phaneendra Manda8db7d092016-06-04 00:17:24 +05303 *
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 */
16package org.onosproject.sfc.installer.impl;
17
18import static com.google.common.base.Preconditions.checkNotNull;
19import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE;
20import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI;
21import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI;
22import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST;
23import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC;
24import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE;
25import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP;
26import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH;
27import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH;
28import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT_TABLE;
29import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1;
30import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2;
31import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3;
32import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4;
33import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI;
34import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI;
35import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
36import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP;
37import static org.slf4j.LoggerFactory.getLogger;
38
39import java.util.LinkedList;
40import java.util.List;
41import java.util.ListIterator;
42import java.util.Set;
43
44import org.onlab.osgi.DefaultServiceDirectory;
45import org.onlab.osgi.ServiceDirectory;
46import org.onlab.packet.Ethernet;
47import org.onlab.packet.IPv4;
48import org.onlab.packet.Ip4Address;
49import org.onlab.packet.IpPrefix;
50import org.onlab.packet.MacAddress;
51import org.onlab.packet.TpPort;
52import org.onosproject.core.ApplicationId;
53import org.onosproject.net.AnnotationKeys;
54import org.onosproject.net.ConnectPoint;
55import org.onosproject.net.Device;
56import org.onosproject.net.DeviceId;
57import org.onosproject.net.Host;
58import org.onosproject.net.HostId;
59import org.onosproject.net.NshContextHeader;
60import org.onosproject.net.NshServiceIndex;
61import org.onosproject.net.NshServicePathId;
62import org.onosproject.net.Port;
63import org.onosproject.net.PortNumber;
64import org.onosproject.net.behaviour.BridgeConfig;
65import org.onosproject.net.behaviour.ExtensionSelectorResolver;
66import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
67import org.onosproject.net.device.DeviceService;
68import org.onosproject.net.driver.DriverHandler;
69import org.onosproject.net.driver.DriverService;
70import org.onosproject.net.flow.DefaultTrafficSelector;
71import org.onosproject.net.flow.DefaultTrafficTreatment;
72import org.onosproject.net.flow.TrafficSelector;
73import org.onosproject.net.flow.TrafficTreatment;
74import org.onosproject.net.flow.criteria.Criteria;
75import org.onosproject.net.flow.criteria.ExtensionSelector;
76import org.onosproject.net.flow.instructions.ExtensionTreatment;
77import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
78import org.onosproject.net.flow.instructions.Instructions;
79import org.onosproject.net.flowobjective.DefaultForwardingObjective;
80import org.onosproject.net.flowobjective.FlowObjectiveService;
81import org.onosproject.net.flowobjective.ForwardingObjective;
82import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
83import org.onosproject.net.flowobjective.Objective;
84import org.onosproject.net.host.HostService;
85import org.onosproject.sfc.installer.SfcFlowRuleInstallerService;
86import org.onosproject.vtnrsc.FiveTuple;
87import org.onosproject.vtnrsc.FlowClassifier;
88import org.onosproject.vtnrsc.FlowClassifierId;
89import org.onosproject.vtnrsc.PortChain;
90import org.onosproject.vtnrsc.PortPair;
91import org.onosproject.vtnrsc.PortPairGroup;
92import org.onosproject.vtnrsc.PortPairGroupId;
93import org.onosproject.vtnrsc.PortPairId;
94import org.onosproject.vtnrsc.SegmentationId;
95import org.onosproject.vtnrsc.VirtualPort;
96import org.onosproject.vtnrsc.VirtualPortId;
97import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
98import org.onosproject.vtnrsc.portpair.PortPairService;
99import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
100import org.onosproject.vtnrsc.service.VtnRscService;
101import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
102import org.onosproject.vtnrsc.virtualport.VirtualPortService;
103import org.slf4j.Logger;
104
105import com.google.common.collect.Lists;
106import com.google.common.collect.Sets;
107
108/**
109 * Provides flow classifier installer implementation.
110 */
111public class SfcFlowRuleInstallerImpl implements SfcFlowRuleInstallerService {
112 private final Logger log = getLogger(getClass());
113
114 protected VirtualPortService virtualPortService;
115 protected VtnRscService vtnRscService;
116 protected PortPairService portPairService;
117 protected PortPairGroupService portPairGroupService;
118 protected FlowClassifierService flowClassifierService;
119 protected DriverService driverService;
120 protected DeviceService deviceService;
121 protected HostService hostService;
122 protected TenantNetworkService tenantNetworkService;
123 protected FlowObjectiveService flowObjectiveService;
124 protected ApplicationId appId;
125
126 private static final String PORT_CHAIN_NOT_NULL = "Port-Chain cannot be null";
127 private static final int FLOW_CLASSIFIER_PRIORITY = 0xC738;
128 private static final int DEFAULT_FORWARDER_PRIORITY = 0xD6D8;
129 private static final int ENCAP_OUTPUT_PRIORITY = 0x64;
130 private static final int TUNNEL_SEND_PRIORITY = 0xC8;
131 private static final String SWITCH_CHANNEL_ID = "channelId";
132 private static final int ENCAP_OUTPUT_TABLE = 4;
133 private static final int TUNNEL_SEND_TABLE = 7;
134 private static final short ENCAP_ETH_TYPE = (short) 0x894f;
135 private static final String DEFAULT_IP = "0.0.0.0";
136 private static final String VXLANPORT_HEAD = "vxlan-0.0.0.0";
137
138 /* Port chain params */
139 private short nshSi;
140 List<DeviceId> classifierList;
141 List<DeviceId> forwarderList;
142
143 /**
144 * Default constructor.
145 */
146 public SfcFlowRuleInstallerImpl() {
147 }
148
149 /**
150 * Explicit constructor.
151 *
152 * @param appId application id.
153 */
154 public SfcFlowRuleInstallerImpl(ApplicationId appId) {
155 this.appId = checkNotNull(appId, "ApplicationId can not be null");
156 ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
157 this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
158 this.driverService = serviceDirectory.get(DriverService.class);
159 this.deviceService = serviceDirectory.get(DeviceService.class);
160 this.hostService = serviceDirectory.get(HostService.class);
161 this.virtualPortService = serviceDirectory.get(VirtualPortService.class);
162 this.vtnRscService = serviceDirectory.get(VtnRscService.class);
163 this.portPairService = serviceDirectory.get(PortPairService.class);
164 this.portPairGroupService = serviceDirectory.get(PortPairGroupService.class);
165 this.flowClassifierService = serviceDirectory.get(FlowClassifierService.class);
166 this.tenantNetworkService = serviceDirectory.get(TenantNetworkService.class);
167 nshSi = 0xff;
168 }
169
170 @Override
171 public ConnectPoint installFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) {
172 checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
173 // Get the portPairGroup
174 List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups();
175 ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator();
176 PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next();
177 PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId);
178 List<PortPairId> llPortPairIdList = portPairGroup.portPairs();
179
180 // Get port pair
181 ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator();
182 PortPairId portPairId = portPairListIterator.next();
183 PortPair portPair = portPairService.getPortPair(portPairId);
184
185 return installSfcClassifierRules(portChain, portPair, nshSpiId, null, Objective.Operation.ADD);
186 }
187
188 @Override
189 public ConnectPoint unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) {
190 checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
191 // Get the portPairGroup
192 List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups();
193 ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator();
194 PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next();
195 PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId);
196 List<PortPairId> llPortPairIdList = portPairGroup.portPairs();
197
198 // Get port pair
199 ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator();
200 PortPairId portPairId = portPairListIterator.next();
201 PortPair portPair = portPairService.getPortPair(portPairId);
202
203 return installSfcClassifierRules(portChain, portPair, nshSpiId, null, Objective.Operation.REMOVE);
204 }
205
206 @Override
207 public ConnectPoint installLoadBalancedFlowRules(PortChain portChain, FiveTuple fiveTuple,
208 NshServicePathId nshSpiId) {
209 checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
210
211 return installSfcFlowRules(portChain, fiveTuple, nshSpiId, Objective.Operation.ADD);
212 }
213
214 @Override
215 public ConnectPoint unInstallLoadBalancedFlowRules(PortChain portChain, FiveTuple fiveTuple,
216 NshServicePathId nshSpiId) {
217 checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
218 return installSfcFlowRules(portChain, fiveTuple, nshSpiId, Objective.Operation.REMOVE);
219 }
220
Phaneendra Mandab212bc92016-07-08 16:50:11 +0530221 @Override
222 public ConnectPoint unInstallLoadBalancedClassifierRules(PortChain portChain, FiveTuple fiveTuple,
223 NshServicePathId nshSpiId) {
224 checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
225
226 List<PortPairId> portPairs = portChain.getLoadBalancePath(fiveTuple);
227 // Get the first port pair
228 ListIterator<PortPairId> portPairListIterator = portPairs.listIterator();
229 PortPairId portPairId = portPairListIterator.next();
230 PortPair portPair = portPairService.getPortPair(portPairId);
231
232 return installSfcClassifierRules(portChain, portPair, nshSpiId, fiveTuple, Objective.Operation.REMOVE);
233 }
234
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530235 public ConnectPoint installSfcFlowRules(PortChain portChain, FiveTuple fiveTuple, NshServicePathId nshSpiId,
236 Objective.Operation type) {
237 checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
238
239 classifierList = Lists.newArrayList();
240 forwarderList = Lists.newArrayList();
241
242 // Get the load balanced path
243 List<PortPairId> portPairs = portChain.getLoadBalancePath(fiveTuple);
244
245 // Get the first port pair
246 ListIterator<PortPairId> portPairListIterator = portPairs.listIterator();
247 PortPairId portPairId = portPairListIterator.next();
248 PortPair currentPortPair = portPairService.getPortPair(portPairId);
249
250 ConnectPoint connectPoint = installSfcClassifierRules(portChain, currentPortPair, nshSpiId, fiveTuple, type);
251
252 log.info("Installing encap and output for first port pair");
253
254 installSfcEncapOutputRule(currentPortPair, nshSpiId, type);
255
256 PortPair nextPortPair;
257 while (portPairListIterator.hasNext()) {
258 portPairId = portPairListIterator.next();
259 nextPortPair = portPairService.getPortPair(portPairId);
260 installSfcForwardRule(currentPortPair, nextPortPair, nshSpiId, type);
261 installSfcEncapOutputRule(nextPortPair, nshSpiId, type);
262 currentPortPair = nextPortPair;
263 }
264 installSfcEndRule(currentPortPair, nshSpiId, type);
265
266 if (type.equals(Objective.Operation.ADD)) {
267 portChain.addSfcClassifiers(portChain.getLoadBalanceId(fiveTuple), classifierList);
268 portChain.addSfcForwarders(portChain.getLoadBalanceId(fiveTuple), forwarderList);
269 } else {
270 portChain.removeSfcClassifiers(portChain.getLoadBalanceId(fiveTuple), classifierList);
271 portChain.removeSfcForwarders(portChain.getLoadBalanceId(fiveTuple), forwarderList);
272 }
273 return connectPoint;
274 }
275
276 public void installSfcTunnelReceiveRule(DeviceId deviceId, NshServicePathId nshSpiId, Objective.Operation type) {
277
278 DriverHandler handler = driverService.createHandler(deviceId);
279 ExtensionSelectorResolver selectorResolver = handler.behaviour(ExtensionSelectorResolver.class);
280 ExtensionSelector nshSpiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type());
281 ExtensionSelector nshSiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type());
282
283 try {
284 nshSpiSelector.setPropertyValue("nshSpi", nshSpiId);
285 } catch (Exception e) {
286 log.error("Failed to set extension selector to match Nsh Spi Id for end rule {}", e.getMessage());
287 }
288 try {
289 nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi));
290 } catch (Exception e) {
291 log.error("Failed to set extension selector to match Nsh Si Id for end rule {}", e.getMessage());
292 }
293
294 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
295 selector.extension(nshSpiSelector, deviceId);
296 selector.extension(nshSiSelector, deviceId);
297
298 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
299 treatment.transition(ENCAP_OUTPUT_TABLE);
300
301 sendSfcRule(selector, treatment, deviceId, type, DEFAULT_FORWARDER_PRIORITY);
302 }
303
304 public void installSfcTunnelSendRule(DeviceId deviceId, NshServicePathId nshSpiId, Objective.Operation type) {
305
306 // Prepare selector with nsp, nsi and inport from egress of port pair
307 DriverHandler handler = driverService.createHandler(deviceId);
308 ExtensionSelectorResolver selectorResolver = handler.behaviour(ExtensionSelectorResolver.class);
309 ExtensionSelector nshSpiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type());
310 ExtensionSelector nshSiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type());
311 ExtensionSelector encapEthTypeSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_ENCAP_ETH_TYPE
312 .type());
313 try {
314 nshSpiSelector.setPropertyValue("nshSpi", nshSpiId);
315 } catch (Exception e) {
316 log.error("Failed to set extension selector to match Nsh Spi Id for end rule {}", e.getMessage());
317 }
318 try {
319 nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi));
320 } catch (Exception e) {
321 log.error("Failed to set extension selector to match Nsh Si Id for end rule {}", e.getMessage());
322 }
323 try {
324 encapEthTypeSelector.setPropertyValue("encapEthType", ENCAP_ETH_TYPE);
325 } catch (Exception e) {
326 log.error("Failed to set extension selector to match encapEthType {}", deviceId);
327 }
328
329 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
330 selector.extension(nshSpiSelector, deviceId);
331 selector.extension(nshSiSelector, deviceId);
332
333 ExtensionTreatmentResolver treatmentResolver = handler.behaviour(ExtensionTreatmentResolver.class);
334 ExtensionTreatment tunGpeNpTreatment = treatmentResolver.getExtensionInstruction(NICIRA_TUN_GPE_NP.type());
335 try {
336 tunGpeNpTreatment.setPropertyValue("tunGpeNp", ((byte) 4));
337 } catch (Exception e) {
338 log.error("Failed to get extension instruction to set tunGpeNp {}", deviceId);
339 }
340
341 ExtensionTreatment moveC1ToC1 = treatmentResolver
342 .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
343 .NICIRA_MOV_NSH_C1_TO_C1.type());
344
345 ExtensionTreatment moveC2ToC2 = treatmentResolver
346 .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
347 .NICIRA_MOV_NSH_C2_TO_C2.type());
348
349 ExtensionTreatment moveC3ToC3 = treatmentResolver
350 .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
351 .NICIRA_MOV_NSH_C3_TO_C3.type());
352
353 ExtensionTreatment moveC4ToC4 = treatmentResolver
354 .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
355 .NICIRA_MOV_NSH_C4_TO_C4.type());
356
357 ExtensionTreatment moveTunIpv4DstToTunIpv4Dst = treatmentResolver
358 .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
359 .NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST.type());
360
361 ExtensionTreatment moveTunIdToTunId = treatmentResolver
362 .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
363 .NICIRA_MOV_TUN_ID_TO_TUN_ID.type());
364
365 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
366 treatment.extension(tunGpeNpTreatment, deviceId);
367 treatment.extension(moveC1ToC1, deviceId);
368 treatment.extension(moveC2ToC2, deviceId);
369 treatment.extension(moveC3ToC3, deviceId);
370 treatment.extension(moveC4ToC4, deviceId);
371 treatment.extension(moveTunIpv4DstToTunIpv4Dst, deviceId);
372 treatment.extension(moveTunIdToTunId, deviceId);
373
374 Iterable<Device> devices = deviceService.getAvailableDevices();
375 DeviceId localControllerId = getControllerId(deviceService.getDevice(deviceId), devices);
376 DriverHandler controllerHandler = driverService.createHandler(localControllerId);
377
378 BridgeConfig bridgeConfig = controllerHandler.behaviour(BridgeConfig.class);
379 Set<PortNumber> ports = bridgeConfig.getPortNumbers();
380 String tunnelName = "vxlan-" + DEFAULT_IP;
381 ports.stream()
Ray Milkey88cc3432017-03-30 17:19:08 -0700382 .filter(p -> p.name().equalsIgnoreCase(tunnelName))
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530383 .forEach(p -> {
384 treatment.setOutput(p);
385 sendSfcRule(selector, treatment, deviceId, type, TUNNEL_SEND_PRIORITY);
386 });
387 }
388
389 public void installSfcEndRule(PortPair portPair, NshServicePathId nshSpiId, Objective.Operation type) {
390 DeviceId deviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.egress()));
391 MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress();
392 Host host = hostService.getHost(HostId.hostId(srcMacAddress));
393 PortNumber port = host.location().port();
394
395 // Prepare selector with nsp, nsi and inport from egress of port pair
396 DriverHandler handler = driverService.createHandler(deviceId);
397 ExtensionSelectorResolver selectorResolver = handler.behaviour(ExtensionSelectorResolver.class);
398 ExtensionSelector nshSpiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type());
399 ExtensionSelector nshSiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type());
400 ExtensionSelector encapEthTypeSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_ENCAP_ETH_TYPE
401 .type());
402 try {
403 nshSpiSelector.setPropertyValue("nshSpi", nshSpiId);
404 } catch (Exception e) {
405 log.error("Failed to set extension selector to match Nsh Spi Id for end rule {}", e.getMessage());
406 }
407 // Decrement the SI
408 nshSi = (short) (nshSi - 1);
409 try {
410 nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi));
411 } catch (Exception e) {
412 log.error("Failed to set extension selector to match Nsh Si Id for end rule {}", e.getMessage());
413 }
414 try {
415 encapEthTypeSelector.setPropertyValue("encapEthType", ENCAP_ETH_TYPE);
416 } catch (Exception e) {
417 log.error("Failed to set extension selector to match encapEthType {}", deviceId);
418 }
419 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
420 selector.extension(encapEthTypeSelector, deviceId);
421 selector.extension(nshSpiSelector, deviceId);
422 selector.extension(nshSiSelector, deviceId);
423 selector.matchInPort(port);
424
425 // Set treatment to pop nsh header, set tunnel id and resubmit to table
426 // 0.
427 ExtensionTreatmentResolver treatmentResolver = handler.behaviour(ExtensionTreatmentResolver.class);
428 ExtensionTreatment popNshTreatment = treatmentResolver.getExtensionInstruction(NICIRA_POP_NSH.type());
429
430 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
431 treatment.extension(popNshTreatment, deviceId);
432
433 VirtualPort virtualPort = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress()));
434 SegmentationId segmentationId = tenantNetworkService.getNetwork(virtualPort.networkId()).segmentationId();
435 treatment.add(Instructions.modTunnelId(Long.parseLong(segmentationId.toString())));
436
437 ExtensionTreatment resubmitTableTreatment = treatmentResolver.getExtensionInstruction(NICIRA_RESUBMIT_TABLE
438 .type());
439
440 PortNumber vxlanPortNumber = getVxlanPortNumber(deviceId);
441
442 try {
443 resubmitTableTreatment.setPropertyValue("inPort", vxlanPortNumber);
444 } catch (Exception e) {
445 log.error("Failed to set extension treatment for resubmit table in port {}", deviceId);
446 }
447 try {
448 resubmitTableTreatment.setPropertyValue("table", ((short) 0));
449 } catch (Exception e) {
450 log.error("Failed to set extension treatment for resubmit table {}", deviceId);
451 }
452 treatment.extension(resubmitTableTreatment, deviceId);
453
454 sendSfcRule(selector, treatment, deviceId, type, DEFAULT_FORWARDER_PRIORITY);
455 }
456
457 public void installSfcForwardRule(PortPair portPair, PortPair nextPortPair, NshServicePathId nshSpiId,
458 Objective.Operation type) {
459 DeviceId deviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.egress()));
460 MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress();
461 Host host = hostService.getHost(HostId.hostId(srcMacAddress));
462 PortNumber port = host.location().port();
463
464 DriverHandler handler = driverService.createHandler(deviceId);
465 ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class);
466
467 // Prepare selector with nsp, nsi and inport from egress of port pair
468 ExtensionSelector nshSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type());
469 ExtensionSelector nshSiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type());
470 try {
471 nshSpiSelector.setPropertyValue("nshSpi", nshSpiId);
472 } catch (Exception e) {
473 log.error("Failed to set extension selector to match Nsh Spi Id for forward rule {}", e.getMessage());
474 }
475 // Decrement the SI
476 nshSi = (short) (nshSi - 1);
477 try {
478 nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi));
479 } catch (Exception e) {
480 log.error("Failed to set extension selector to match Nsh Si Id for forward rule {}", e.getMessage());
481 }
482 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
483 selector.extension(nshSpiSelector, deviceId);
484 selector.extension(nshSiSelector, deviceId);
485 selector.matchInPort(port);
486
487 DeviceId nextDeviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(nextPortPair.ingress()));
488 if (deviceId.equals(nextDeviceId)) {
489
490 // Treatment with transition
491 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
492 treatment.transition(ENCAP_OUTPUT_TABLE);
493
494 sendSfcRule(selector, treatment, deviceId, type, DEFAULT_FORWARDER_PRIORITY);
495 } else {
496 // Treatment with with transition to send on tunnel
497 ExtensionTreatmentResolver treatmentResolver = handler.behaviour(ExtensionTreatmentResolver.class);
498 ExtensionTreatment moveC2ToTunId = treatmentResolver
499 .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
500 .NICIRA_MOV_NSH_C2_TO_TUN_ID.type());
501
502 Device remoteDevice = deviceService.getDevice(nextDeviceId);
503 String url = remoteDevice.annotations().value(SWITCH_CHANNEL_ID);
504 String remoteControllerIp = url.substring(0, url.lastIndexOf(":"));
505 if (remoteControllerIp == null) {
506 log.error("Can't find remote controller of device: {}", nextDeviceId.toString());
507 return;
508 }
509
510 ExtensionTreatment tunnelDsttreatment = treatmentResolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST
511 .type());
512 try {
513 tunnelDsttreatment.setPropertyValue("tunnelDst", Ip4Address.valueOf(remoteControllerIp));
514 } catch (Exception e) {
515 log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
516 }
517
518 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
519 treatment.extension(moveC2ToTunId, deviceId);
520 treatment.extension(tunnelDsttreatment, deviceId);
521 treatment.transition(TUNNEL_SEND_TABLE);
522
523 sendSfcRule(selector, treatment, deviceId, type, DEFAULT_FORWARDER_PRIORITY);
524
525 installSfcTunnelSendRule(deviceId, nshSpiId, type);
526 installSfcTunnelReceiveRule(nextDeviceId, nshSpiId, type);
527 }
528 }
529
530 public void installSfcEncapOutputRule(PortPair portPair, NshServicePathId nshSpiId, Objective.Operation type) {
531
532 DeviceId deviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress()));
533 MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress();
534 Host host = hostService.getHost(HostId.hostId(srcMacAddress));
535 PortNumber port = host.location().port();
536
537 DriverHandler handler = driverService.createHandler(deviceId);
538 ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class);
539
540 // Prepare selector with nsp, nsi and encap eth type
541 ExtensionSelector nshSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type());
542 ExtensionSelector nshSiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type());
543 ExtensionSelector nshEncapEthTypeSelector = resolver.getExtensionSelector(NICIRA_MATCH_ENCAP_ETH_TYPE.type());
544
545 try {
546 nshSpiSelector.setPropertyValue("nshSpi", nshSpiId);
547 } catch (Exception e) {
548 log.error("Failed to set extension selector to match Nsh Spi Id for encap rule {}", e.getMessage());
549 }
550 try {
551 nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi));
552 } catch (Exception e) {
553 log.error("Failed to set extension selector to match Nsh Si Id for encap rule {}", e.getMessage());
554 }
555 try {
556 nshEncapEthTypeSelector.setPropertyValue("encapEthType", ENCAP_ETH_TYPE);
557 } catch (Exception e) {
558 log.error("Failed to set extension selector to match Nsh Si Id {}", deviceId);
559 }
560 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
561 selector.extension(nshSpiSelector, deviceId);
562 selector.extension(nshSiSelector, deviceId);
563
564 ExtensionTreatmentResolver treatmentResolver = handler.behaviour(ExtensionTreatmentResolver.class);
565 ExtensionTreatment encapEthSrcTreatment = treatmentResolver
566 .getExtensionInstruction(NICIRA_ENCAP_ETH_SRC.type());
567 ExtensionTreatment encapEthDstTreatment = treatmentResolver
568 .getExtensionInstruction(NICIRA_ENCAP_ETH_DST.type());
569
570 try {
571 encapEthDstTreatment.setPropertyValue("encapEthDst", srcMacAddress);
572 } catch (Exception e) {
573 log.error("Failed to set extension treatment to set encap eth dst {}", deviceId);
574 }
575 // TODO: move from packet source mac address
576 try {
577 encapEthSrcTreatment.setPropertyValue("encapEthSrc", srcMacAddress);
578 } catch (Exception e) {
579 log.error("Failed to set extension treatment to set encap eth src {}", deviceId);
580 }
581
582 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
583 treatment.extension(encapEthSrcTreatment, deviceId);
584 treatment.extension(encapEthDstTreatment, deviceId);
585 treatment.setOutput(port);
586
587 sendSfcRule(selector, treatment, deviceId, type, ENCAP_OUTPUT_PRIORITY);
588 forwarderList.add(deviceId);
589 }
590
591 public ConnectPoint installSfcClassifierRules(PortChain portChain, PortPair portPair, NshServicePathId nshSpiId,
592 FiveTuple fiveTuple, Objective.Operation type) {
593
594 DeviceId deviceIdfromPortPair = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress()));
595 MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress();
596 VirtualPort virtualPort = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress()));
597 Host host = hostService.getHost(HostId.hostId(srcMacAddress));
598 PortNumber port = host.location().port();
599
600 DeviceId deviceId = deviceIdfromPortPair;
601
602 // get flow classifiers
603 List<FlowClassifierId> llFlowClassifierList = portChain.flowClassifiers();
604 ListIterator<FlowClassifierId> flowClassifierListIterator = llFlowClassifierList.listIterator();
605
606 while (flowClassifierListIterator.hasNext()) {
607 FlowClassifierId flowclassifierId = flowClassifierListIterator.next();
608 FlowClassifier flowClassifier = flowClassifierService.getFlowClassifier(flowclassifierId);
609
610 if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) {
611 deviceId = vtnRscService.getSfToSffMaping(flowClassifier.srcPort());
612 }
613
614 // Build Traffic selector.
615 TrafficSelector.Builder selector = packClassifierSelector(flowClassifier, fiveTuple);
616
617 if (fiveTuple == null) {
618 // Send the packet to controller
619 log.info("Downloading rule to send packet to controller");
620 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
621 treatment.setOutput(PortNumber.CONTROLLER);
622 sendSfcRule(selector, treatment, deviceId, type, FLOW_CLASSIFIER_PRIORITY);
623 continue;
624 }
625
626 if (deviceId != null && !deviceId.equals(deviceIdfromPortPair)) {
627 // First SF is in another device. Set tunnel ipv4 destination to
628 // treatment
629 Device remoteDevice = deviceService.getDevice(deviceIdfromPortPair);
630 String url = remoteDevice.annotations().value(SWITCH_CHANNEL_ID);
631 String remoteControllerIp = url.substring(0, url.lastIndexOf(":"));
632 if (remoteControllerIp == null) {
633 log.error("Can't find remote controller of device: {}", deviceIdfromPortPair.toString());
634 return null;
635 }
636
637 DriverHandler handler = driverService.createHandler(deviceId);
638 ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
639 ExtensionTreatment tunnelDsttreatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
640 try {
641 tunnelDsttreatment.setPropertyValue("tunnelDst", Ip4Address.valueOf(remoteControllerIp));
642 } catch (Exception e) {
643 log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
644 }
645
646 TrafficTreatment.Builder treatment = packClassifierTreatment(deviceId, virtualPort, port,
647 nshSpiId, flowClassifier);
648 treatment.extension(tunnelDsttreatment, deviceId);
649 treatment.transition(TUNNEL_SEND_TABLE);
650 sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
Phaneendra Mandab212bc92016-07-08 16:50:11 +0530651
652 selector.matchInPort(PortNumber.CONTROLLER);
653 sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
654 classifierList.add(deviceId);
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530655
656 installSfcTunnelSendRule(deviceId, nshSpiId, type);
657 installSfcTunnelReceiveRule(deviceIdfromPortPair, nshSpiId, type);
658
659 } else {
660 // classifier and port pair are in the same OVS. So directly
661 // send packet to first port pair
662 TrafficTreatment.Builder treatment = packClassifierTreatment(deviceIdfromPortPair, virtualPort, port,
663 nshSpiId, flowClassifier);
664 treatment.transition(ENCAP_OUTPUT_TABLE);
665 sendSfcRule(selector, treatment, deviceIdfromPortPair, type, flowClassifier.priority());
Phaneendra Mandab212bc92016-07-08 16:50:11 +0530666
667 selector.matchInPort(PortNumber.CONTROLLER);
668 sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530669 classifierList.add(deviceIdfromPortPair);
670 }
671 }
672
673 return host.location();
674 }
675
676 /**
677 * Pack Traffic selector.
678 *
679 * @param flowClassifier flow-classifier
680 * @param fiveTuple five tuple info for the packet
681 * @return traffic selector
682 */
683 public TrafficSelector.Builder packClassifierSelector(FlowClassifier flowClassifier, FiveTuple fiveTuple) {
684
685 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
686
687 if ((flowClassifier.srcIpPrefix() != null) && (flowClassifier.srcIpPrefix().prefixLength() != 0)) {
688 selector.matchIPSrc(flowClassifier.srcIpPrefix());
689 } else if (fiveTuple != null && fiveTuple.ipSrc() != null) {
690 selector.matchIPSrc(IpPrefix.valueOf(fiveTuple.ipSrc(), 24));
691 }
692
693 if ((flowClassifier.dstIpPrefix() != null) && (flowClassifier.dstIpPrefix().prefixLength() != 0)) {
694 selector.matchIPDst(flowClassifier.dstIpPrefix());
695 } else if (fiveTuple != null && fiveTuple.ipDst() != null) {
696 selector.matchIPDst(IpPrefix.valueOf(fiveTuple.ipDst(), 24));
697 }
698
699 if ((flowClassifier.protocol() != null) && (!flowClassifier.protocol().isEmpty())) {
Jon Halla3fcf672017-03-28 16:53:22 -0700700 if ("TCP".equalsIgnoreCase(flowClassifier.protocol())) {
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530701 selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_TCP));
Jon Halla3fcf672017-03-28 16:53:22 -0700702 } else if ("UDP".equalsIgnoreCase(flowClassifier.protocol())) {
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530703 selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP));
Jon Halla3fcf672017-03-28 16:53:22 -0700704 } else if ("ICMP".equalsIgnoreCase(flowClassifier.protocol())) {
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530705 selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_ICMP));
706 }
707 } else if (fiveTuple != null && fiveTuple.protocol() != 0) {
708 selector.add(Criteria.matchIPProtocol(fiveTuple.protocol()));
709 }
710
711 if (((flowClassifier.etherType() != null) && (!flowClassifier.etherType().isEmpty()))
Jon Halla3fcf672017-03-28 16:53:22 -0700712 && ("IPv4".equals(flowClassifier.etherType()) || "IPv6".equals(flowClassifier.etherType()))) {
713 if ("IPv4".equals(flowClassifier.etherType())) {
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530714 selector.matchEthType(Ethernet.TYPE_IPV4);
715 } else {
716 selector.matchEthType(Ethernet.TYPE_IPV6);
717 }
718 }
719
720 if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) {
721 VirtualPortId vPortId = VirtualPortId.portId(flowClassifier.srcPort().portId());
722 MacAddress macAddress = virtualPortService.getPort(vPortId).macAddress();
723 Host host = hostService.getHost(HostId.hostId(macAddress));
724 selector.matchInPort(host.location().port());
725 }
726
727 // Take the port information from five tuple only when the protocol is
728 // TCP.
729 if (fiveTuple != null && fiveTuple.protocol() == IPv4.PROTOCOL_TCP) {
730 selector.matchTcpSrc(TpPort.tpPort((int) fiveTuple.portSrc().toLong()));
731 selector.matchTcpDst(TpPort.tpPort((int) fiveTuple.portDst().toLong()));
732 } else {
733 // For udp packets take the port information from flow classifier
734 List<TpPort> srcPortRange = new LinkedList<>();
735 List<TpPort> dstPortRange = new LinkedList<>();
736 if ((flowClassifier.minSrcPortRange() != 0) && flowClassifier.maxSrcPortRange() != 0
737 && flowClassifier.minDstPortRange() != 0 && flowClassifier.maxDstPortRange() != 0) {
738
739 for (int port = flowClassifier.minSrcPortRange(); port <= flowClassifier.maxSrcPortRange(); port++) {
740 srcPortRange.add(TpPort.tpPort(port));
741 }
742 for (int port = flowClassifier.minDstPortRange(); port <= flowClassifier.maxDstPortRange(); port++) {
743 dstPortRange.add(TpPort.tpPort(port));
744 }
745 }
746
747 for (TpPort inPort : srcPortRange) {
748 selector.matchUdpSrc(inPort);
749 }
750 for (TpPort outPort : dstPortRange) {
751 selector.matchUdpDst(outPort);
752 }
753 }
754 return selector;
755 }
756
757 /**
758 * Pack traffic treatment.
759 *
760 * @param deviceId device id
761 * @param virtualPort virtual port
762 * @param port port number
763 * @param nshSpi nsh spi
764 * @param flowClassifier flow-classifier
765 * @return traffic treatment
766 */
767 public TrafficTreatment.Builder packClassifierTreatment(DeviceId deviceId, VirtualPort virtualPort,
768 PortNumber port, NshServicePathId nshSpi, FlowClassifier flowClassifier) {
769
770 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
771
772 // set tunnel id
773 SegmentationId segmentationId = tenantNetworkService.getNetwork(virtualPort.networkId()).segmentationId();
774 treatmentBuilder.add(Instructions.modTunnelId(Long.parseLong(segmentationId.toString())));
775
776 // Set all NSH header fields
777 DriverHandler handler = driverService.createHandler(deviceId);
778 ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
779 ExtensionTreatment nspIdTreatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_SPI.type());
780 ExtensionTreatment nsiIdTreatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_SI.type());
781 ExtensionTreatment pushNshTreatment = resolver.getExtensionInstruction(NICIRA_PUSH_NSH.type());
782
783 ExtensionTreatment nshCh1Treatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_CH1.type());
784 ExtensionTreatment nshCh2Treatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_CH2.type());
785 ExtensionTreatment nshCh3Treatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_CH3.type());
786 ExtensionTreatment nshCh4Treatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_CH4.type());
787 ExtensionTreatment nshMdTypeTreatment = resolver.getExtensionInstruction(NICIRA_NSH_MDTYPE.type());
788 ExtensionTreatment nshNpTreatment = resolver.getExtensionInstruction(NICIRA_NSH_NP.type());
789
790 try {
791 nshMdTypeTreatment.setPropertyValue("nshMdType", ((byte) 1));
792 } catch (Exception e) {
793 log.error("Failed to get extension instruction to set nshMdType {}", deviceId);
794 }
795 try {
796 nshNpTreatment.setPropertyValue("nshNp", ((byte) 3));
797 } catch (Exception e) {
798 log.error("Failed to get extension instruction to set nshNp {}", deviceId);
799 }
800 try {
801 nspIdTreatment.setPropertyValue("nshSpi", nshSpi);
802 } catch (Exception e) {
803 log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId);
804 }
805 try {
806 nsiIdTreatment.setPropertyValue("nshSi", NshServiceIndex.of(nshSi));
807 } catch (Exception e) {
808 log.error("Failed to get extension instruction to set Nsh Si Id {}", deviceId);
809 }
810 try {
811 nshCh1Treatment.setPropertyValue("nshCh", NshContextHeader.of(1));
812 } catch (Exception e) {
813 log.error("Failed to get extension instruction to set NshCh1 {}", deviceId);
814 }
815 try {
816 nshCh2Treatment.setPropertyValue("nshCh", NshContextHeader.of(Integer.parseInt(segmentationId.toString())));
817 } catch (Exception e) {
818 log.error("Failed to get extension instruction to set NshCh2 {}", deviceId);
819 }
820 try {
821 nshCh3Treatment.setPropertyValue("nshCh", NshContextHeader.of(3));
822 } catch (Exception e) {
823 log.error("Failed to get extension instruction to set NshCh3 {}", deviceId);
824 }
825 try {
826 nshCh4Treatment.setPropertyValue("nshCh", NshContextHeader.of(4));
827 } catch (Exception e) {
828 log.error("Failed to get extension instruction to set NshCh4 {}", deviceId);
829 }
830 treatmentBuilder.extension(pushNshTreatment, deviceId);
831 treatmentBuilder.extension(nshMdTypeTreatment, deviceId);
832 treatmentBuilder.extension(nshNpTreatment, deviceId);
833 treatmentBuilder.extension(nspIdTreatment, deviceId);
834 treatmentBuilder.extension(nsiIdTreatment, deviceId);
835 treatmentBuilder.extension(nshCh1Treatment, deviceId);
836 treatmentBuilder.extension(nshCh2Treatment, deviceId);
837 treatmentBuilder.extension(nshCh3Treatment, deviceId);
838 treatmentBuilder.extension(nshCh4Treatment, deviceId);
839
840 return treatmentBuilder;
841 }
842
843 /**
844 * Get the ControllerId from the device .
845 *
846 * @param device Device
847 * @param devices Devices
848 * @return Controller Id
849 */
850 public DeviceId getControllerId(Device device, Iterable<Device> devices) {
851 for (Device d : devices) {
852 if (d.type() == Device.Type.CONTROLLER && d.id().toString()
853 .contains(getControllerIpOfSwitch(device))) {
854 return d.id();
855 }
856 }
857 log.info("Can not find controller for device : {}", device.id());
858 return null;
859 }
860
861 /**
862 * Get the ControllerIp from the device .
863 *
864 * @param device Device
865 * @return Controller Ip
866 */
867 public String getControllerIpOfSwitch(Device device) {
868 String url = device.annotations().value(SWITCH_CHANNEL_ID);
869 return url.substring(0, url.lastIndexOf(":"));
870 }
871
872 /**
873 * Send service-function-forwarder to OVS.
874 *
875 * @param selector traffic selector
876 * @param treatment traffic treatment
877 * @param deviceId device id
878 * @param type operation type
879 * @param priority priority of classifier
880 */
881 public void sendSfcRule(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment, DeviceId deviceId,
882 Objective.Operation type, int priority) {
883
884 log.info("Sending sfc flow rule. Selector {}, Treatment {}", selector.toString(),
885 treatment.toString());
886 ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build())
887 .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.VERSATILE)
888 .withPriority(priority);
889
890 if (type.equals(Objective.Operation.ADD)) {
891 log.debug("flowClassifierRules-->ADD");
892 flowObjectiveService.forward(deviceId, objective.add());
893 } else {
894 log.debug("flowClassifierRules-->REMOVE");
895 flowObjectiveService.forward(deviceId, objective.remove());
896 }
897 }
898
899 private PortNumber getVxlanPortNumber(DeviceId deviceId) {
900 Iterable<Port> ports = deviceService.getPorts(deviceId);
901 Port vxlanPort = Sets.newHashSet(ports).stream()
Ray Milkey88cc3432017-03-30 17:19:08 -0700902 .filter(p -> !p.number().equals(PortNumber.LOCAL))
903 .filter(p -> p.annotations().value(AnnotationKeys.PORT_NAME)
Phaneendra Manda8db7d092016-06-04 00:17:24 +0530904 .startsWith(VXLANPORT_HEAD))
905 .findFirst().get();
906 return vxlanPort.number();
907 }
908}