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.netvirt.openstack.netvirt.sfc.workaround.services;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.List;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
20 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
21 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.Service;
22 import org.opendaylight.netvirt.openstack.netvirt.sfc.NshUtils;
23 import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
24 import org.opendaylight.netvirt.openstack.netvirt.providers.ConfigInterface;
25 import org.opendaylight.netvirt.openstack.netvirt.sfc.ISfcClassifierService;
26 import org.opendaylight.netvirt.utils.mdsal.openflow.ActionUtils;
27 import org.opendaylight.netvirt.utils.mdsal.openflow.FlowUtils;
28 import org.opendaylight.netvirt.utils.mdsal.openflow.InstructionUtils;
29 import org.opendaylight.netvirt.utils.mdsal.openflow.MatchUtils;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.osgi.framework.BundleContext;
52 import org.osgi.framework.ServiceReference;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
57 private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
58 private static final short UDP_SHORT = 17;
59 static int cookieIndex = 0;
60 private FlowCache flowCache = new FlowCache();
63 FLOW_INGRESSCLASS(1), FLOW_SFINGRESS(2), FLOW_SFEGRESS(3), FLOW_SFARP(4),
64 FLOW_EGRESSCLASSUNUSED(5), FLOW_EGRESSCLASS(6), FLOW_EGRESSCLASSBYPASS(7), FLOW_SFCTABLE(8);
72 private BigInteger getCookie(FlowID flowID) {
73 String cookieString = String.format("1110%02d%010d", flowID.value, cookieIndex++);
74 return new BigInteger(cookieString, 16);
77 private BigInteger getCookie(FlowID flowID, short nsp, short nsi) {
78 String cookieString = String.format("1110%02d%03d%03d0%03d", flowID.value, 0, nsp, nsi);
79 return new BigInteger(cookieString, 16);
82 public SfcClassifierService(Service service) {
86 public SfcClassifierService() {
87 super(Service.SFC_CLASSIFIER);
91 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
92 super.setDependencies(bundleContext.getServiceReference(ISfcClassifierService.class.getName()), this);
96 public void setDependencies(Object impl) {}
98 private FlowBuilder initFlowBuilder(FlowBuilder flowBuilder, String flowName, short table, FlowID flowID) {
99 FlowUtils.initFlowBuilder(flowBuilder, flowName, table)
100 .setCookie(new FlowCookie(getCookie(flowID)))
101 .setCookieMask(new FlowCookie(getCookie(flowID)));
105 private FlowBuilder initFlowBuilder(FlowBuilder flowBuilder, String flowName, short table, FlowID flowID,
106 short nsp, short nsi) {
107 FlowUtils.initFlowBuilder(flowBuilder, flowName, table)
108 .setCookie(new FlowCookie(getCookie(flowID, nsp, nsi)))
109 .setCookieMask(new FlowCookie(getCookie(flowID, nsp, nsi)));
113 private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder, String rspName, FlowID flowID) {
114 flowCache.addFlow(flowBuilder, nodeBuilder, rspName, flowID.value);
115 writeFlow(flowBuilder, nodeBuilder);
118 private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder, String rspName, FlowID flowID) {
119 flowCache.removeFlow(rspName, flowID.value);
120 removeFlow(flowBuilder, nodeBuilder);
124 public void programIngressClassifier(long dataPathId, String ruleName, Matches matches, long nsp, short nsi,
125 NshUtils nshHeader, long vxGpeOfPort, String rspName, boolean write) {
126 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
127 FlowBuilder flowBuilder = new FlowBuilder();
128 String flowName = FlowNames.getSfcIngressClass(ruleName, nsp, nsi);
129 initFlowBuilder(flowBuilder, flowName, getTable(), FlowID.FLOW_INGRESSCLASS,
130 (short)nshHeader.getNshNsp(), nshHeader.getNshNsi());
132 MatchBuilder matchBuilder = new AclMatches(matches).buildMatch();
133 MatchUtils.addNxRegMatch(matchBuilder,
134 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
135 flowBuilder.setMatch(matchBuilder.build());
138 ActionBuilder ab = new ActionBuilder();
139 List<Action> actionList = new ArrayList<>();
141 ab.setAction(ActionUtils.nxMoveTunIdtoNshc2());
142 ab.setOrder(actionList.size());
143 ab.setKey(new ActionKey(actionList.size()));
144 actionList.add(ab.build());
146 getNshAction(nshHeader, actionList);
148 if (vxGpeOfPort != 0) {
149 ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
150 ab.setOrder(actionList.size());
151 ab.setKey(new ActionKey(actionList.size()));
152 actionList.add(ab.build());
154 ab.setAction(ActionUtils.nxResubmitAction(null, Service.CLASSIFIER.getTable()));
155 ab.setOrder(actionList.size());
156 ab.setKey(new ActionKey(actionList.size()));
157 actionList.add(ab.build());
160 ApplyActionsBuilder aab = new ApplyActionsBuilder();
161 aab.setAction(actionList);
163 InstructionBuilder ib = new InstructionBuilder();
164 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
166 ib.setKey(new InstructionKey(0));
167 List<Instruction> instructions = new ArrayList<>();
168 instructions.add(ib.build());
170 InstructionsBuilder isb = new InstructionsBuilder();
171 isb.setInstruction(instructions);
172 flowBuilder.setInstructions(isb.build());
173 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_INGRESSCLASS);
175 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_INGRESSCLASS);
180 public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
181 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
182 FlowBuilder flowBuilder = new FlowBuilder();
183 String flowName = FlowNames.getSfcTable(vxGpeOfPort);
184 initFlowBuilder(flowBuilder, flowName, getTable(Service.CLASSIFIER), FlowID.FLOW_SFCTABLE)
187 MatchBuilder matchBuilder = new MatchBuilder();
188 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
189 flowBuilder.setMatch(matchBuilder.build());
192 InstructionsBuilder isb = new InstructionsBuilder();
193 List<Instruction> instructions = new ArrayList<>();
194 InstructionBuilder ib =
195 InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
197 ib.setKey(new InstructionKey(0));
198 instructions.add(ib.build());
200 isb.setInstruction(instructions);
201 flowBuilder.setInstructions(isb.build());
202 writeFlow(flowBuilder, nodeBuilder);
204 removeFlow(flowBuilder, nodeBuilder);
209 public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
210 int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
211 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
212 FlowBuilder flowBuilder = new FlowBuilder();
213 String flowName = FlowNames.getSfcEgressClass1(vxGpeOfPort);
214 initFlowBuilder(flowBuilder, flowName, getTable(Service.CLASSIFIER), FlowID.FLOW_EGRESSCLASSUNUSED,
217 MatchBuilder matchBuilder = new MatchBuilder();
218 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
219 MatchUtils.addNxNspMatch(matchBuilder, nsp);
220 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
221 flowBuilder.setMatch(matchBuilder.build());
224 InstructionsBuilder isb = new InstructionsBuilder();
225 List<Instruction> instructions = new ArrayList<>();
227 InstructionBuilder ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
228 ib.setOrder(instructions.size());
229 ib.setKey(new InstructionKey(instructions.size()));
230 instructions.add(ib.build());
232 isb.setInstruction(instructions);
233 flowBuilder.setInstructions(isb.build());
234 writeFlow(flowBuilder, nodeBuilder);
236 removeFlow(flowBuilder, nodeBuilder);
241 public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
242 long sfOfPort, int tunnelId, String rspName, boolean write) {
243 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
244 FlowBuilder flowBuilder = new FlowBuilder();
245 String flowName = FlowNames.getSfcEgressClass(vxGpeOfPort, nsp, nsi);
246 initFlowBuilder(flowBuilder, flowName, getTable(Service.SFC_CLASSIFIER), FlowID.FLOW_EGRESSCLASS,
249 MatchBuilder matchBuilder = new MatchBuilder();
250 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
251 MatchUtils.addNxNspMatch(matchBuilder, nsp);
252 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
253 flowBuilder.setMatch(matchBuilder.build());
256 InstructionsBuilder isb = new InstructionsBuilder();
257 List<Instruction> instructions = new ArrayList<>();
258 List<Action> actionList = new ArrayList<>();
260 ActionBuilder ab = new ActionBuilder();
263 ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(FlowUtils.REG_FIELD).build(),
264 BigInteger.valueOf(FlowUtils.REG_VALUE_FROM_LOCAL)));
265 ab.setOrder(actionList.size());
266 ab.setKey(new ActionKey(actionList.size()));
267 actionList.add(ab.build());
269 ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
270 ab.setOrder(actionList.size());
271 ab.setKey(new ActionKey(actionList.size()));
272 actionList.add(ab.build());
274 ab.setAction(ActionUtils.nxResubmitAction((int)sfOfPort, getTable(Service.CLASSIFIER)));
275 ab.setOrder(actionList.size());
276 ab.setKey(new ActionKey(actionList.size()));
277 actionList.add(ab.build());
279 ApplyActionsBuilder aab = new ApplyActionsBuilder();
280 aab.setAction(actionList);
281 InstructionBuilder ib = new InstructionBuilder();
282 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
285 ib.setKey(new InstructionKey(0));
286 instructions.add(ib.build());
288 isb.setInstruction(instructions);
289 flowBuilder.setInstructions(isb.build());
290 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_EGRESSCLASS);
292 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_EGRESSCLASS);
297 public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
298 long sfOfPort, int tunnelId, String rspName, boolean write) {
299 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
300 FlowBuilder flowBuilder = new FlowBuilder();
301 String flowName = FlowNames.getSfcEgressClassBypass(nsp, nsi, sfOfPort);
302 initFlowBuilder(flowBuilder, flowName, getTable(Service.CLASSIFIER),
303 FlowID.FLOW_EGRESSCLASSBYPASS, (short)nsp, nsi)
306 MatchBuilder matchBuilder = new MatchBuilder();
307 MatchUtils.createInPortMatch(matchBuilder, dataPathId, sfOfPort);
308 MatchUtils.addNxRegMatch(matchBuilder,
309 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
310 MatchUtils.addNxNspMatch(matchBuilder, nsp);
311 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
312 flowBuilder.setMatch(matchBuilder.build());
315 ActionBuilder ab = new ActionBuilder();
316 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action popNshAction =
317 ActionUtils.nxPopNshAction();
318 ab.setAction(popNshAction);
320 ab.setKey(new ActionKey(0));
322 List<Action> actionList = new ArrayList<>();
323 actionList.add(ab.build());
325 ApplyActionsBuilder aab = new ApplyActionsBuilder();
326 aab.setAction(actionList);
328 InstructionBuilder popNshIb = new InstructionBuilder();
329 popNshIb.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
330 popNshIb.setOrder(0);
331 popNshIb.setKey(new InstructionKey(0));
333 // This will do a goto table
334 InstructionBuilder mutableIb;
335 mutableIb = this.getMutablePipelineInstructionBuilder();
336 mutableIb.setOrder(1);
337 mutableIb.setKey(new InstructionKey(1));
339 List<Instruction> instructions = new ArrayList<>();
340 instructions.add(popNshIb.build());
341 instructions.add(mutableIb.build());
343 InstructionsBuilder isb = new InstructionsBuilder();
344 isb.setInstruction(instructions);
345 flowBuilder.setInstructions(isb.build());
346 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_EGRESSCLASSBYPASS);
348 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_EGRESSCLASSBYPASS);
352 // packet from sf to sff that need to go out local
354 public void program_sfEgress(long dataPathId, int dstPort, String rspName, boolean write) {
355 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
356 FlowBuilder flowBuilder = new FlowBuilder();
357 String flowName = FlowNames.getSfEgress(dstPort);
358 initFlowBuilder(flowBuilder, flowName, getTable(), FlowID.FLOW_SFEGRESS);
360 MatchBuilder matchBuilder = new MatchBuilder();
361 MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
362 MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
363 MatchUtils.addNxRegMatch(matchBuilder,
364 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
365 flowBuilder.setMatch(matchBuilder.build());
368 InstructionBuilder ib = new InstructionBuilder();
369 InstructionsBuilder isb = new InstructionsBuilder();
370 List<Instruction> instructions = new ArrayList<>();
371 InstructionUtils.createLocalInstructions(ib, dataPathId);
373 ib.setKey(new InstructionKey(0));
374 instructions.add(ib.build());
376 isb.setInstruction(instructions);
377 flowBuilder.setInstructions(isb.build());
378 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFEGRESS);
380 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFEGRESS);
384 // looped back sff to sf packets
386 public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
387 String ipAddress, String sfDplName, String rspName, boolean write) {
388 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
389 FlowBuilder flowBuilder = new FlowBuilder();
390 String flowName = FlowNames.getSfIngress(dstPort, ipAddress);
391 initFlowBuilder(flowBuilder, flowName, Service.CLASSIFIER.getTable(), FlowID.FLOW_SFINGRESS);
393 MatchBuilder matchBuilder = new MatchBuilder();
394 MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
395 Ipv4Prefix ipCidr = MatchUtils.iPv4PrefixFromIPv4Address(ipAddress);
396 MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(ipCidr));
397 MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
398 flowBuilder.setMatch(matchBuilder.build());
401 InstructionBuilder ib = new InstructionBuilder();
402 InstructionsBuilder isb = new InstructionsBuilder();
403 List<Instruction> instructions = new ArrayList<>();
404 InstructionUtils.createOutputPortInstructions(ib, dataPathId, sfOfPort);
407 ib.setKey(new InstructionKey(0));
408 instructions.add(ib.build());
410 isb.setInstruction(instructions);
411 flowBuilder.setInstructions(isb.build());
412 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFINGRESS);
414 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFINGRESS);
419 public void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
420 String ipAddress, String rspName, boolean write) {
421 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
422 FlowBuilder flowBuilder = new FlowBuilder();
423 String flowName = FlowNames.getArpResponder(ipAddress);
424 initFlowBuilder(flowBuilder, flowName, getTable(Service.ARP_RESPONDER), FlowID.FLOW_SFARP)
427 MacAddress macAddress = new MacAddress(macAddressStr);
429 MatchBuilder matchBuilder = new MatchBuilder();
430 MatchUtils.createInPortReservedMatch(matchBuilder, dataPathId, OutputPortValues.LOCAL.toString());
431 MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(Constants.ARP_ETHERTYPE));
432 MatchUtils.createArpDstIpv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress));
433 flowBuilder.setMatch(matchBuilder.build());
436 InstructionBuilder ib = new InstructionBuilder();
437 InstructionsBuilder isb = new InstructionsBuilder();
438 List<Instruction> instructions = new ArrayList<>();
439 ApplyActionsBuilder aab = new ApplyActionsBuilder();
440 ActionBuilder ab = new ActionBuilder();
441 List<Action> actionList = new ArrayList<>();
443 // Move Eth Src to Eth Dst
444 ab.setAction(ActionUtils.nxMoveEthSrcToEthDstAction());
446 ab.setKey(new ActionKey(0));
447 actionList.add(ab.build());
450 ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
452 ab.setKey(new ActionKey(1));
453 actionList.add(ab.build());
456 ab.setAction(ActionUtils.nxLoadArpOpAction(BigInteger.valueOf(FlowUtils.ARP_OP_REPLY)));
458 ab.setKey(new ActionKey(2));
459 actionList.add(ab.build());
461 // Move ARP SHA to ARP THA
462 ab.setAction(ActionUtils.nxMoveArpShaToArpThaAction());
464 ab.setKey(new ActionKey(3));
465 actionList.add(ab.build());
467 // Move ARP SPA to ARP TPA
468 ab.setAction(ActionUtils.nxMoveArpSpaToArpTpaAction());
470 ab.setKey(new ActionKey(4));
471 actionList.add(ab.build());
473 // Load Mac to ARP SHA
474 ab.setAction(ActionUtils.nxLoadArpShaAction(macAddress));
476 ab.setKey(new ActionKey(5));
477 actionList.add(ab.build());
479 // Load IP to ARP SPA
480 ab.setAction(ActionUtils.nxLoadArpSpaAction(ipAddress));
482 ab.setKey(new ActionKey(6));
483 actionList.add(ab.build());
486 ab.setAction(ActionUtils.outputAction(
487 FlowUtils.getSpecialNodeConnectorId(dataPathId, OutputPortValues.INPORT.toString())));
489 ab.setKey(new ActionKey(7));
490 actionList.add(ab.build());
492 // Create Apply Actions Instruction
493 aab.setAction(actionList);
494 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
496 ib.setKey(new InstructionKey(0));
497 instructions.add(ib.build());
499 isb.setInstruction(instructions);
500 flowBuilder.setInstructions(isb.build());
501 writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFARP);
503 removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFARP);
507 private List<Action> getNshAction(NshUtils header, List<Action> actionList) {
508 // Build the Actions to Add the NSH Header
509 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action pushNsh =
510 ActionUtils.nxPushNshAction();
511 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshMdtypeLoad =
512 ActionUtils.nxLoadNshMdtypeAction((short) 0x1);
513 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshNpLoad =
514 ActionUtils.nxLoadNshNpAction((short) 0x3);
515 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
516 ActionUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
517 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nspLoad =
518 ActionUtils.nxSetNspAction(header.getNshNsp());
519 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nsiLoad =
520 ActionUtils.nxSetNsiAction(header.getNshNsi());
521 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
522 ActionUtils.nxLoadTunIdAction(BigInteger.valueOf(header.getNshNsp()), false);
523 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
524 ActionUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
526 int count = actionList.size();
527 actionList.add(new ActionBuilder()
528 .setKey(new ActionKey(count)).setOrder(count++).setAction(pushNsh).build());
529 actionList.add(new ActionBuilder()
530 .setKey(new ActionKey(count)).setOrder(count++).setAction(nshMdtypeLoad).build());
531 actionList.add(new ActionBuilder()
532 .setKey(new ActionKey(count)).setOrder(count++).setAction(nshNpLoad).build());
533 actionList.add(new ActionBuilder()
534 .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC1Load).build());
535 actionList.add(new ActionBuilder()
536 .setKey(new ActionKey(count)).setOrder(count++).setAction(nspLoad).build());
537 actionList.add(new ActionBuilder()
538 .setKey(new ActionKey(count)).setOrder(count++).setAction(nsiLoad).build());
539 actionList.add(new ActionBuilder()
540 .setKey(new ActionKey(count)).setOrder(count++).setAction(loadChainTunDest).build());
541 actionList.add(new ActionBuilder()
542 .setKey(new ActionKey(count)).setOrder(count).setAction(loadChainTunVnid).build());
546 private static FlowID flowSet[] = {FlowID.FLOW_INGRESSCLASS, FlowID.FLOW_EGRESSCLASS,
547 FlowID.FLOW_EGRESSCLASSBYPASS, FlowID.FLOW_SFARP, FlowID.FLOW_SFINGRESS, FlowID.FLOW_SFEGRESS};
550 public void clearFlows(DataBroker dataBroker, String rspName) {
551 Map<Integer, InstanceIdentifier<Flow>> flowMap = flowCache.getFlows(rspName);
552 if (flowMap != null) {
553 for (FlowID flowID : flowSet) {
554 InstanceIdentifier<Flow> path = flowMap.get(flowID.value);
556 flowCache.removeFlow(rspName, flowID.value);
557 removeFlow(dataBroker, path);
563 private void removeFlow(DataBroker dataBroker, InstanceIdentifier<Flow> path) {
564 WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
565 modification.delete(LogicalDatastoreType.CONFIGURATION, path);
567 CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
569 commitFuture.get(); // TODO: Make it async (See bug 1362)
570 LOG.debug("Transaction success for deletion of Flow {}", path);
571 } catch (Exception e) {
572 LOG.error("Failed to remove flow {}", path, e);
573 modification.cancel();