2 * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services;
11 import com.google.common.collect.Lists;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
21 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
22 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
23 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
24 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
25 import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
26 import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
27 import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
28 import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
29 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
30 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
54 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
55 import org.osgi.framework.BundleContext;
56 import org.osgi.framework.ServiceReference;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
60 public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
61 private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
62 private static final short UDP_SHORT = 17;
63 static int cookieIndex = 0;
64 private FlowCache flowCache = new FlowCache();
67 FLOW_INGRESSCLASS(1), FLOW_SFINGRESS(2), FLOW_SFEGRESS(3), FLOW_SFARP(4),
68 FLOW_EGRESSCLASSUNUSED(5), FLOW_EGRESSCLASS(6), FLOW_EGRESSCLASSBYPASS(7), FLOW_SFCTABLE(8);
76 private BigInteger getCookie(FlowID flowID) {
77 String cookieString = String.format("1110%02d%010d", flowID.value, cookieIndex++);
78 return new BigInteger(cookieString, 16);
81 private BigInteger getCookie(FlowID flowID, short nsp, short nsi) {
82 String cookieString = String.format("1110%02d%03d%03d0%03d", flowID.value, 0, nsp, nsi);
83 return new BigInteger(cookieString, 16);
86 public SfcClassifierService(Service service) {
90 public SfcClassifierService() {
91 super(Service.SFC_CLASSIFIER);
95 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
96 super.setDependencies(bundleContext.getServiceReference(ISfcClassifierService.class.getName()), this);
100 public void setDependencies(Object impl) {}
102 private FlowBuilder initFlowBuilder(FlowBuilder flowBuilder, String flowName, short table, FlowID flowID) {
103 FlowUtils.initFlowBuilder(flowBuilder, flowName, table)
104 .setCookie(new FlowCookie(getCookie(flowID)))
105 .setCookieMask(new FlowCookie(getCookie(flowID)));
109 private FlowBuilder initFlowBuilder(FlowBuilder flowBuilder, String flowName, short table, FlowID flowID,
110 short nsp, short nsi) {
111 FlowUtils.initFlowBuilder(flowBuilder, flowName, table)
112 .setCookie(new FlowCookie(getCookie(flowID, nsp, nsi)))
113 .setCookieMask(new FlowCookie(getCookie(flowID, nsp, nsi)));
117 private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder, String rspName, FlowID flowID) {
118 flowCache.addFlow(flowBuilder, nodeBuilder, rspName, flowID.value);
119 writeFlow(flowBuilder, nodeBuilder);
122 private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder, String rspName, FlowID flowID) {
123 flowCache.removeFlow(rspName, flowID.value);
124 removeFlow(flowBuilder, nodeBuilder);
128 public void programIngressClassifier(long dataPathId, String ruleName, Matches matches, long nsp, short nsi,
129 NshUtils nshHeader, long vxGpeOfPort, String rspName, boolean write) {
130 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
131 FlowBuilder flowBuilder = new FlowBuilder();
132 String flowName = FlowNames.getSfcIngressClass(ruleName, nsp, nsi);
133 initFlowBuilder(flowBuilder, flowName, getTable(), FlowID.FLOW_INGRESSCLASS,
134 (short)nshHeader.getNshNsp(), nshHeader.getNshNsi());
136 MatchBuilder matchBuilder = new AclMatches(matches).buildMatch();
137 MatchUtils.addNxRegMatch(matchBuilder,
138 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
139 flowBuilder.setMatch(matchBuilder.build());
142 ActionBuilder ab = new ActionBuilder();
143 List<Action> actionList = new ArrayList<>();
145 ab.setAction(ActionUtils.nxMoveTunIdtoNshc2());
146 ab.setOrder(actionList.size());
147 ab.setKey(new ActionKey(actionList.size()));
148 actionList.add(ab.build());
150 getNshAction(nshHeader, actionList);
152 if (vxGpeOfPort != 0) {
153 ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
154 ab.setOrder(actionList.size());
155 ab.setKey(new ActionKey(actionList.size()));
156 actionList.add(ab.build());
158 ab.setAction(ActionUtils.nxResubmitAction(null, Service.CLASSIFIER.getTable()));
159 ab.setOrder(actionList.size());
160 ab.setKey(new ActionKey(actionList.size()));
161 actionList.add(ab.build());
164 ApplyActionsBuilder aab = new ApplyActionsBuilder();
165 aab.setAction(actionList);
167 InstructionBuilder ib = new InstructionBuilder();
168 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
170 ib.setKey(new InstructionKey(0));
171 List<Instruction> instructions = Lists.newArrayList();
172 instructions.add(ib.build());
174 InstructionsBuilder isb = new InstructionsBuilder();
175 isb.setInstruction(instructions);
176 flowBuilder.setInstructions(isb.build());
177 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_INGRESSCLASS);
179 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_INGRESSCLASS);
184 public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
185 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
186 FlowBuilder flowBuilder = new FlowBuilder();
187 String flowName = FlowNames.getSfcTable(vxGpeOfPort);
188 initFlowBuilder(flowBuilder, flowName, getTable(Service.CLASSIFIER), FlowID.FLOW_SFCTABLE)
191 MatchBuilder matchBuilder = new MatchBuilder();
192 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
193 flowBuilder.setMatch(matchBuilder.build());
196 InstructionsBuilder isb = new InstructionsBuilder();
197 List<Instruction> instructions = Lists.newArrayList();
198 InstructionBuilder ib =
199 InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
201 ib.setKey(new InstructionKey(0));
202 instructions.add(ib.build());
204 isb.setInstruction(instructions);
205 flowBuilder.setInstructions(isb.build());
206 writeFlow(flowBuilder, nodeBuilder);
208 removeFlow(flowBuilder, nodeBuilder);
213 public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
214 int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
215 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
216 FlowBuilder flowBuilder = new FlowBuilder();
217 String flowName = FlowNames.getSfcEgressClass1(vxGpeOfPort);
218 initFlowBuilder(flowBuilder, flowName, getTable(Service.CLASSIFIER), FlowID.FLOW_EGRESSCLASSUNUSED,
221 MatchBuilder matchBuilder = new MatchBuilder();
222 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
223 MatchUtils.addNxNspMatch(matchBuilder, nsp);
224 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
225 flowBuilder.setMatch(matchBuilder.build());
228 InstructionsBuilder isb = new InstructionsBuilder();
229 List<Instruction> instructions = Lists.newArrayList();
231 InstructionBuilder ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
232 ib.setOrder(instructions.size());
233 ib.setKey(new InstructionKey(instructions.size()));
234 instructions.add(ib.build());
236 isb.setInstruction(instructions);
237 flowBuilder.setInstructions(isb.build());
238 writeFlow(flowBuilder, nodeBuilder);
240 removeFlow(flowBuilder, nodeBuilder);
245 public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
246 long sfOfPort, int tunnelId, String rspName, boolean write) {
247 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
248 FlowBuilder flowBuilder = new FlowBuilder();
249 String flowName = FlowNames.getSfcEgressClass(vxGpeOfPort, nsp, nsi);
250 initFlowBuilder(flowBuilder, flowName, getTable(Service.SFC_CLASSIFIER), FlowID.FLOW_EGRESSCLASS,
253 MatchBuilder matchBuilder = new MatchBuilder();
254 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
255 MatchUtils.addNxNspMatch(matchBuilder, nsp);
256 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
257 flowBuilder.setMatch(matchBuilder.build());
260 InstructionsBuilder isb = new InstructionsBuilder();
261 List<Instruction> instructions = Lists.newArrayList();
262 List<Action> actionList = Lists.newArrayList();
264 ActionBuilder ab = new ActionBuilder();
267 ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(FlowUtils.REG_FIELD).build(),
268 BigInteger.valueOf(FlowUtils.REG_VALUE_FROM_LOCAL)));
269 ab.setOrder(actionList.size());
270 ab.setKey(new ActionKey(actionList.size()));
271 actionList.add(ab.build());
273 ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
274 ab.setOrder(actionList.size());
275 ab.setKey(new ActionKey(actionList.size()));
276 actionList.add(ab.build());
278 ab.setAction(ActionUtils.nxResubmitAction((int)sfOfPort, getTable(Service.CLASSIFIER)));
279 ab.setOrder(actionList.size());
280 ab.setKey(new ActionKey(actionList.size()));
281 actionList.add(ab.build());
283 ApplyActionsBuilder aab = new ApplyActionsBuilder();
284 aab.setAction(actionList);
285 InstructionBuilder ib = new InstructionBuilder();
286 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
289 ib.setKey(new InstructionKey(0));
290 instructions.add(ib.build());
292 isb.setInstruction(instructions);
293 flowBuilder.setInstructions(isb.build());
294 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_EGRESSCLASS);
296 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_EGRESSCLASS);
301 public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
302 long sfOfPort, int tunnelId, String rspName, boolean write) {
303 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
304 FlowBuilder flowBuilder = new FlowBuilder();
305 String flowName = FlowNames.getSfcEgressClassBypass(nsp, nsi, sfOfPort);
306 initFlowBuilder(flowBuilder, flowName, getTable(Service.CLASSIFIER),
307 FlowID.FLOW_EGRESSCLASSBYPASS, (short)nsp, nsi)
310 MatchBuilder matchBuilder = new MatchBuilder();
311 MatchUtils.createInPortMatch(matchBuilder, dataPathId, sfOfPort);
312 MatchUtils.addNxRegMatch(matchBuilder,
313 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
314 MatchUtils.addNxNspMatch(matchBuilder, nsp);
315 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
316 flowBuilder.setMatch(matchBuilder.build());
319 InstructionsBuilder isb = new InstructionsBuilder();
320 List<Instruction> instructions = Lists.newArrayList();
322 InstructionBuilder ib;
323 ib = this.getMutablePipelineInstructionBuilder();
325 ib.setKey(new InstructionKey(0));
326 instructions.add(ib.build());
328 isb.setInstruction(instructions);
329 flowBuilder.setInstructions(isb.build());
330 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_EGRESSCLASSBYPASS);
332 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_EGRESSCLASSBYPASS);
336 // packet from sf to sff that need to go out local
338 public void program_sfEgress(long dataPathId, int dstPort, String rspName, boolean write) {
339 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
340 FlowBuilder flowBuilder = new FlowBuilder();
341 String flowName = FlowNames.getSfEgress(dstPort);
342 initFlowBuilder(flowBuilder, flowName, getTable(), FlowID.FLOW_SFEGRESS);
344 MatchBuilder matchBuilder = new MatchBuilder();
345 MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
346 MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
347 MatchUtils.addNxRegMatch(matchBuilder,
348 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
349 flowBuilder.setMatch(matchBuilder.build());
352 InstructionBuilder ib = new InstructionBuilder();
353 InstructionsBuilder isb = new InstructionsBuilder();
354 List<Instruction> instructions = Lists.newArrayList();
355 InstructionUtils.createLocalInstructions(ib, dataPathId);
357 ib.setKey(new InstructionKey(0));
358 instructions.add(ib.build());
360 isb.setInstruction(instructions);
361 flowBuilder.setInstructions(isb.build());
362 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFEGRESS);
364 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFEGRESS);
368 // looped back sff to sf packets
370 public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
371 String ipAddress, String sfDplName, String rspName, boolean write) {
372 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
373 FlowBuilder flowBuilder = new FlowBuilder();
374 String flowName = FlowNames.getSfIngress(dstPort, ipAddress);
375 initFlowBuilder(flowBuilder, flowName, Service.CLASSIFIER.getTable(), FlowID.FLOW_SFINGRESS);
377 MatchBuilder matchBuilder = new MatchBuilder();
378 MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
379 Ipv4Prefix ipCidr = MatchUtils.iPv4PrefixFromIPv4Address(ipAddress);
380 MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(ipCidr));
381 MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
382 flowBuilder.setMatch(matchBuilder.build());
385 InstructionBuilder ib = new InstructionBuilder();
386 InstructionsBuilder isb = new InstructionsBuilder();
387 List<Instruction> instructions = Lists.newArrayList();
388 InstructionUtils.createOutputPortInstructions(ib, dataPathId, sfOfPort);
391 ib.setKey(new InstructionKey(0));
392 instructions.add(ib.build());
394 isb.setInstruction(instructions);
395 flowBuilder.setInstructions(isb.build());
396 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFINGRESS);
398 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFINGRESS);
403 public void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
404 String ipAddress, String rspName, boolean write) {
405 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
406 FlowBuilder flowBuilder = new FlowBuilder();
407 String flowName = FlowNames.getArpResponder(ipAddress);
408 initFlowBuilder(flowBuilder, flowName, getTable(Service.ARP_RESPONDER), FlowID.FLOW_SFARP)
411 MacAddress macAddress = new MacAddress(macAddressStr);
413 MatchBuilder matchBuilder = new MatchBuilder();
414 MatchUtils.createInPortReservedMatch(matchBuilder, dataPathId, OutputPortValues.LOCAL.toString());
415 MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(Constants.ARP_ETHERTYPE));
416 MatchUtils.createArpDstIpv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress));
417 flowBuilder.setMatch(matchBuilder.build());
420 InstructionBuilder ib = new InstructionBuilder();
421 InstructionsBuilder isb = new InstructionsBuilder();
422 List<Instruction> instructions = Lists.newArrayList();
423 ApplyActionsBuilder aab = new ApplyActionsBuilder();
424 ActionBuilder ab = new ActionBuilder();
425 List<Action> actionList = Lists.newArrayList();
427 // Move Eth Src to Eth Dst
428 ab.setAction(ActionUtils.nxMoveEthSrcToEthDstAction());
430 ab.setKey(new ActionKey(0));
431 actionList.add(ab.build());
434 ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
436 ab.setKey(new ActionKey(1));
437 actionList.add(ab.build());
440 ab.setAction(ActionUtils.nxLoadArpOpAction(BigInteger.valueOf(FlowUtils.ARP_OP_REPLY)));
442 ab.setKey(new ActionKey(2));
443 actionList.add(ab.build());
445 // Move ARP SHA to ARP THA
446 ab.setAction(ActionUtils.nxMoveArpShaToArpThaAction());
448 ab.setKey(new ActionKey(3));
449 actionList.add(ab.build());
451 // Move ARP SPA to ARP TPA
452 ab.setAction(ActionUtils.nxMoveArpSpaToArpTpaAction());
454 ab.setKey(new ActionKey(4));
455 actionList.add(ab.build());
457 // Load Mac to ARP SHA
458 ab.setAction(ActionUtils.nxLoadArpShaAction(macAddress));
460 ab.setKey(new ActionKey(5));
461 actionList.add(ab.build());
463 // Load IP to ARP SPA
464 ab.setAction(ActionUtils.nxLoadArpSpaAction(ipAddress));
466 ab.setKey(new ActionKey(6));
467 actionList.add(ab.build());
470 ab.setAction(ActionUtils.outputAction(
471 FlowUtils.getSpecialNodeConnectorId(dataPathId, OutputPortValues.INPORT.toString())));
473 ab.setKey(new ActionKey(7));
474 actionList.add(ab.build());
476 // Create Apply Actions Instruction
477 aab.setAction(actionList);
478 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
480 ib.setKey(new InstructionKey(0));
481 instructions.add(ib.build());
483 isb.setInstruction(instructions);
484 flowBuilder.setInstructions(isb.build());
485 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFARP);
487 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFARP);
491 private List<Action> getNshAction(NshUtils header, List<Action> actionList) {
492 // Build the Actions to Add the NSH Header
493 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
494 ActionUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
495 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nspLoad =
496 ActionUtils.nxSetNspAction(header.getNshNsp());
497 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nsiLoad =
498 ActionUtils.nxSetNsiAction(header.getNshNsi());
499 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
500 ActionUtils.nxLoadTunIdAction(BigInteger.valueOf(header.getNshNsp()), false);
501 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
502 ActionUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
504 int count = actionList.size();
505 actionList.add(new ActionBuilder()
506 .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC1Load).build());
507 actionList.add(new ActionBuilder()
508 .setKey(new ActionKey(count)).setOrder(count++).setAction(nspLoad).build());
509 actionList.add(new ActionBuilder()
510 .setKey(new ActionKey(count)).setOrder(count++).setAction(nsiLoad).build());
511 actionList.add(new ActionBuilder()
512 .setKey(new ActionKey(count)).setOrder(count++).setAction(loadChainTunDest).build());
513 actionList.add(new ActionBuilder()
514 .setKey(new ActionKey(count)).setOrder(count).setAction(loadChainTunVnid).build());
518 private static FlowID flowSet[] = {FlowID.FLOW_INGRESSCLASS, FlowID.FLOW_EGRESSCLASS,
519 FlowID.FLOW_EGRESSCLASSBYPASS, FlowID.FLOW_SFARP, FlowID.FLOW_SFINGRESS, FlowID.FLOW_SFEGRESS};
522 public void clearFlows(DataBroker dataBroker, String rspName) {
523 Map<Integer, InstanceIdentifier<Flow>> flowMap = flowCache.getFlows(rspName);
524 if (flowMap != null) {
525 for (FlowID flowID : flowSet) {
526 InstanceIdentifier<Flow> path = flowMap.get(flowID.value);
528 flowCache.removeFlow(rspName, flowID.value);
529 removeFlow(dataBroker, path);
535 private void removeFlow(DataBroker dataBroker, InstanceIdentifier<Flow> path) {
536 WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
537 modification.delete(LogicalDatastoreType.CONFIGURATION, path);
539 CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
541 commitFuture.get(); // TODO: Make it async (See bug 1362)
542 LOG.debug("Transaction success for deletion of Flow {}", path);
543 } catch (Exception e) {
544 LOG.error("Failed to remove flow {}", path, e);
545 modification.cancel();