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 java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.List;
15 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
16 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
17 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
18 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
19 import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
20 import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
21 import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
22 import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
23 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
24 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
25 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;
26 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;
27 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;
28 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;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
49 import org.osgi.framework.BundleContext;
50 import org.osgi.framework.ServiceReference;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
54 public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
55 private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
56 private static final short TABLE_0 = 0;
57 private static final short UDP_SHORT = 17;
58 static int cookieIndex = 0;
61 FLOW_INGRESSCLASS(1), FLOW_SFINGRESS(2), FLOW_SFEGRESS(3), FLOW_SFARP(4),
62 FLOW_EGRESSCLASSUNUSED(5), FLOW_EGRESSCLASS(6), FLOW_EGRESSCLASSBYPASS(7), FLOW_SFCTABLE(8);
71 //private AtomicLong flowCookieInc = new AtomicLong(0x1L);
72 private BigInteger getCookie(FlowID flowID) {
73 String cookieString = new String().format("1110%02d%010d", flowID.value, cookieIndex++);
74 //new String().format("1100%02d00%04d", flowID.value, flowCookieInc.getAndIncrement());
75 // "1100%02000000d%04d"
76 return new BigInteger(cookieString, 16);
79 public SfcClassifierService(Service service) {
83 public SfcClassifierService() {
84 super(Service.SFC_CLASSIFIER);
88 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
89 super.setDependencies(bundleContext.getServiceReference(ISfcClassifierService.class.getName()), this);
93 public void setDependencies(Object impl) {}
96 public void programIngressClassifier(long dataPathId, String ruleName, Matches matches,
97 NshUtils nshHeader, long vxGpeOfPort, boolean write) {
98 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
99 FlowBuilder flowBuilder = new FlowBuilder();
101 MatchBuilder matchBuilder = buildMatch(matches);
102 MatchUtils.addNxRegMatch(matchBuilder,
103 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
104 MatchUtils.addNxRegMatch(matchBuilder,
105 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
106 flowBuilder.setMatch(matchBuilder.build());
108 String flowId = "sfcIngressClass_" + ruleName;// + "_" + nshHeader.getNshNsp();
109 flowBuilder.setId(new FlowId(flowId));
110 FlowKey key = new FlowKey(new FlowId(flowId));
111 flowBuilder.setBarrier(true);
112 flowBuilder.setTableId(getTable());
113 flowBuilder.setKey(key);
114 flowBuilder.setFlowName(flowId);
115 flowBuilder.setHardTimeout(0);
116 flowBuilder.setIdleTimeout(0);
117 flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_INGRESSCLASS)));
120 ActionBuilder ab = new ActionBuilder();
121 List<Action> actionList = new ArrayList<>();
123 ab.setAction(ActionUtils.nxMoveTunIdtoNshc2());
124 ab.setOrder(actionList.size());
125 ab.setKey(new ActionKey(actionList.size()));
126 actionList.add(ab.build());
128 getNshAction(nshHeader, actionList);
130 ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
131 ab.setOrder(actionList.size());
132 ab.setKey(new ActionKey(actionList.size()));
133 actionList.add(ab.build());
135 ApplyActionsBuilder aab = new ApplyActionsBuilder();
136 aab.setAction(actionList);
138 InstructionBuilder ib = new InstructionBuilder();
139 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
141 ib.setKey(new InstructionKey(0));
142 List<Instruction> instructions = Lists.newArrayList();
143 instructions.add(ib.build());
145 InstructionsBuilder isb = new InstructionsBuilder();
146 isb.setInstruction(instructions);
147 flowBuilder.setInstructions(isb.build());
148 writeFlow(flowBuilder, nodeBuilder);
150 removeFlow(flowBuilder, nodeBuilder);
155 public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
156 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
157 FlowBuilder flowBuilder = new FlowBuilder();
159 MatchBuilder matchBuilder = new MatchBuilder();
160 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
161 flowBuilder.setMatch(matchBuilder.build());
163 String flowId = "sfcTable_" + vxGpeOfPort;
164 flowBuilder.setId(new FlowId(flowId));
165 FlowKey key = new FlowKey(new FlowId(flowId));
166 flowBuilder.setBarrier(true);
167 flowBuilder.setTableId(TABLE_0);
168 flowBuilder.setKey(key);
169 flowBuilder.setFlowName(flowId);
170 flowBuilder.setHardTimeout(0);
171 flowBuilder.setIdleTimeout(0);
172 flowBuilder.setPriority(1000);
173 flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFCTABLE)));
174 flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFCTABLE)));
177 InstructionsBuilder isb = new InstructionsBuilder();
178 List<Instruction> instructions = Lists.newArrayList();
179 InstructionBuilder ib =
180 InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
182 ib.setKey(new InstructionKey(0));
183 instructions.add(ib.build());
185 isb.setInstruction(instructions);
186 flowBuilder.setInstructions(isb.build());
187 writeFlow(flowBuilder, nodeBuilder);
189 removeFlow(flowBuilder, nodeBuilder);
194 public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
195 int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
196 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
197 FlowBuilder flowBuilder = new FlowBuilder();
199 MatchBuilder matchBuilder = new MatchBuilder();
200 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
201 MatchUtils.addNxNspMatch(matchBuilder, nsp);
202 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
203 flowBuilder.setMatch(matchBuilder.build());
205 String flowId = "sfcEgressClass1_" + vxGpeOfPort;
206 flowBuilder.setId(new FlowId(flowId));
207 FlowKey key = new FlowKey(new FlowId(flowId));
208 flowBuilder.setBarrier(true);
209 flowBuilder.setTableId(TABLE_0);
210 flowBuilder.setKey(key);
211 flowBuilder.setFlowName(flowId);
212 flowBuilder.setHardTimeout(0);
213 flowBuilder.setIdleTimeout(0);
214 flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSUNUSED)));
215 flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSUNUSED)));
218 InstructionsBuilder isb = new InstructionsBuilder();
219 List<Instruction> instructions = Lists.newArrayList();
220 InstructionBuilder ib = new InstructionBuilder();
222 /*List<Action> actionList = Lists.newArrayList();
224 ActionBuilder ab = new ActionBuilder();
225 ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
227 ab.setKey(new ActionKey(0));
228 actionList.add(ab.build());
230 ApplyActionsBuilder aab = new ApplyActionsBuilder();
231 aab.setAction(actionList);
232 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
234 ib.setOrder(instructions.size());
235 ib.setKey(new InstructionKey(instructions.size()));
236 instructions.add(ib.build());*/
238 ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
239 ib.setOrder(instructions.size());
240 ib.setKey(new InstructionKey(instructions.size()));
241 instructions.add(ib.build());
243 isb.setInstruction(instructions);
244 flowBuilder.setInstructions(isb.build());
245 writeFlow(flowBuilder, nodeBuilder);
247 removeFlow(flowBuilder, nodeBuilder);
252 public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
253 long sfOfPort, int tunnelId, boolean write) {
254 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
255 FlowBuilder flowBuilder = new FlowBuilder();
257 MatchBuilder matchBuilder = new MatchBuilder();
258 MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
259 MatchUtils.addNxNspMatch(matchBuilder, nsp);
260 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
261 flowBuilder.setMatch(matchBuilder.build());
263 String flowId = "sfcEgressClass_" + nsp + "_" + + nsi + "_" + vxGpeOfPort;
264 flowBuilder.setId(new FlowId(flowId));
265 FlowKey key = new FlowKey(new FlowId(flowId));
266 flowBuilder.setBarrier(true);
267 flowBuilder.setTableId(TABLE_0);
268 flowBuilder.setKey(key);
269 flowBuilder.setFlowName(flowId);
270 flowBuilder.setHardTimeout(0);
271 flowBuilder.setIdleTimeout(0);
272 flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASS)));
273 flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASS)));
276 InstructionsBuilder isb = new InstructionsBuilder();
277 List<Instruction> instructions = Lists.newArrayList();
278 List<Action> actionList = Lists.newArrayList();
280 ActionBuilder ab = new ActionBuilder();
283 ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(FlowUtils.REG_FIELD).build(),
284 BigInteger.valueOf(FlowUtils.REG_VALUE_FROM_LOCAL)));
285 ab.setOrder(actionList.size());
286 ab.setKey(new ActionKey(actionList.size()));
287 actionList.add(ab.build());
289 ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
290 ab.setOrder(actionList.size());
291 ab.setKey(new ActionKey(actionList.size()));
292 actionList.add(ab.build());
294 ab.setAction(ActionUtils.nxResubmitAction((int)sfOfPort, TABLE_0));
295 ab.setOrder(actionList.size());
296 ab.setKey(new ActionKey(actionList.size()));
297 actionList.add(ab.build());
299 ApplyActionsBuilder aab = new ApplyActionsBuilder();
300 aab.setAction(actionList);
301 InstructionBuilder ib = new InstructionBuilder();
302 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
305 ib.setKey(new InstructionKey(0));
306 instructions.add(ib.build());
308 isb.setInstruction(instructions);
309 flowBuilder.setInstructions(isb.build());
310 writeFlow(flowBuilder, nodeBuilder);
312 removeFlow(flowBuilder, nodeBuilder);
317 public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
318 long sfOfPort, int tunnelId, boolean write) {
319 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
320 FlowBuilder flowBuilder = new FlowBuilder();
322 MatchBuilder matchBuilder = new MatchBuilder();
323 MatchUtils.createInPortMatch(matchBuilder, dataPathId, sfOfPort);
324 MatchUtils.addNxRegMatch(matchBuilder,
325 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
326 MatchUtils.addNxNspMatch(matchBuilder, nsp);
327 MatchUtils.addNxNsiMatch(matchBuilder, nsi);
328 flowBuilder.setMatch(matchBuilder.build());
330 String flowId = "sfcEgressClassBypass_" + nsp + "_" + + nsi + "_" + sfOfPort;
331 flowBuilder.setId(new FlowId(flowId));
332 FlowKey key = new FlowKey(new FlowId(flowId));
333 flowBuilder.setBarrier(true);
334 flowBuilder.setTableId(TABLE_0);
335 flowBuilder.setKey(key);
336 flowBuilder.setFlowName(flowId);
337 flowBuilder.setHardTimeout(0);
338 flowBuilder.setIdleTimeout(0);
339 flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSBYPASS)));
340 flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSBYPASS)));
341 flowBuilder.setPriority(40000); //Needs to be above default priority of 32768
344 InstructionsBuilder isb = new InstructionsBuilder();
345 List<Instruction> instructions = Lists.newArrayList();
347 InstructionBuilder ib;
348 ib = this.getMutablePipelineInstructionBuilder();
350 ib.setKey(new InstructionKey(0));
351 instructions.add(ib.build());
353 isb.setInstruction(instructions);
354 flowBuilder.setInstructions(isb.build());
355 writeFlow(flowBuilder, nodeBuilder);
357 removeFlow(flowBuilder, nodeBuilder);
361 // packet from sf to sff that need to go out local
363 public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
364 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
365 FlowBuilder flowBuilder = new FlowBuilder();
367 MatchBuilder matchBuilder = new MatchBuilder();
368 MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
369 MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
370 MatchUtils.addNxRegMatch(matchBuilder,
371 MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
372 flowBuilder.setMatch(matchBuilder.build());
374 String flowId = "sfEgress_" + dstPort;
375 flowBuilder.setId(new FlowId(flowId));
376 FlowKey key = new FlowKey(new FlowId(flowId));
377 flowBuilder.setBarrier(true);
378 flowBuilder.setTableId(getTable());
379 flowBuilder.setKey(key);
380 flowBuilder.setFlowName(flowId);
381 flowBuilder.setHardTimeout(0);
382 flowBuilder.setIdleTimeout(0);
383 flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFEGRESS)));
384 flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFEGRESS)));
387 InstructionBuilder ib = new InstructionBuilder();
388 InstructionsBuilder isb = new InstructionsBuilder();
389 List<Instruction> instructions = Lists.newArrayList();
390 InstructionUtils.createLocalInstructions(ib, dataPathId);
392 ib.setKey(new InstructionKey(0));
393 instructions.add(ib.build());
395 isb.setInstruction(instructions);
396 flowBuilder.setInstructions(isb.build());
397 writeFlow(flowBuilder, nodeBuilder);
399 removeFlow(flowBuilder, nodeBuilder);
403 // looped back sff to sf packets
405 public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
406 String ipAddress, String sfDplName, boolean write) {
407 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
408 FlowBuilder flowBuilder = new FlowBuilder();
410 MatchBuilder matchBuilder = new MatchBuilder();
411 MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
412 Ipv4Prefix ipCidr = MatchUtils.iPv4PrefixFromIPv4Address(ipAddress);
413 MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(ipCidr));
414 MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
415 flowBuilder.setMatch(matchBuilder.build());
417 String flowId = "sfIngress_" + dstPort + "_" + ipAddress;
418 flowBuilder.setId(new FlowId(flowId));
419 FlowKey key = new FlowKey(new FlowId(flowId));
420 flowBuilder.setBarrier(true);
421 flowBuilder.setTableId(TABLE_0);
422 flowBuilder.setKey(key);
423 flowBuilder.setFlowName(flowId);
424 flowBuilder.setHardTimeout(0);
425 flowBuilder.setIdleTimeout(0);
426 flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFINGRESS)));
427 flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFINGRESS)));
430 InstructionBuilder ib = new InstructionBuilder();
431 InstructionsBuilder isb = new InstructionsBuilder();
432 List<Instruction> instructions = Lists.newArrayList();
433 InstructionUtils.createOutputPortInstructions(ib, dataPathId, sfOfPort);
436 ib.setKey(new InstructionKey(0));
437 instructions.add(ib.build());
439 isb.setInstruction(instructions);
440 flowBuilder.setInstructions(isb.build());
441 writeFlow(flowBuilder, nodeBuilder);
443 removeFlow(flowBuilder, nodeBuilder);
448 public void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
449 String ipAddress, boolean write) {
450 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
451 FlowBuilder flowBuilder = new FlowBuilder();
453 MacAddress macAddress = new MacAddress(macAddressStr);
455 MatchBuilder matchBuilder = new MatchBuilder();
456 MatchUtils.createInPortReservedMatch(matchBuilder, dataPathId, OutputPortValues.LOCAL.toString());
457 MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(Constants.ARP_ETHERTYPE));
458 MatchUtils.createArpDstIpv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress));
459 flowBuilder.setMatch(matchBuilder.build());
461 String flowId = "ArpResponder_" + ipAddress;
462 flowBuilder.setId(new FlowId(flowId));
463 FlowKey key = new FlowKey(new FlowId(flowId));
464 flowBuilder.setBarrier(true);
465 flowBuilder.setTableId(TABLE_0);
466 flowBuilder.setKey(key);
467 flowBuilder.setPriority(1024);
468 flowBuilder.setFlowName(flowId);
469 flowBuilder.setHardTimeout(0);
470 flowBuilder.setIdleTimeout(0);
471 flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFARP)));
472 flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFARP)));
475 InstructionBuilder ib = new InstructionBuilder();
476 InstructionsBuilder isb = new InstructionsBuilder();
477 List<Instruction> instructions = Lists.newArrayList();
478 ApplyActionsBuilder aab = new ApplyActionsBuilder();
479 ActionBuilder ab = new ActionBuilder();
480 List<Action> actionList = Lists.newArrayList();
482 // Move Eth Src to Eth Dst
483 ab.setAction(ActionUtils.nxMoveEthSrcToEthDstAction());
485 ab.setKey(new ActionKey(0));
486 actionList.add(ab.build());
489 ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
491 ab.setKey(new ActionKey(1));
492 actionList.add(ab.build());
495 ab.setAction(ActionUtils.nxLoadArpOpAction(BigInteger.valueOf(FlowUtils.ARP_OP_REPLY)));
497 ab.setKey(new ActionKey(2));
498 actionList.add(ab.build());
500 // Move ARP SHA to ARP THA
501 ab.setAction(ActionUtils.nxMoveArpShaToArpThaAction());
503 ab.setKey(new ActionKey(3));
504 actionList.add(ab.build());
506 // Move ARP SPA to ARP TPA
507 ab.setAction(ActionUtils.nxMoveArpSpaToArpTpaAction());
509 ab.setKey(new ActionKey(4));
510 actionList.add(ab.build());
512 // Load Mac to ARP SHA
513 ab.setAction(ActionUtils.nxLoadArpShaAction(macAddress));
515 ab.setKey(new ActionKey(5));
516 actionList.add(ab.build());
518 // Load IP to ARP SPA
519 ab.setAction(ActionUtils.nxLoadArpSpaAction(ipAddress));
521 ab.setKey(new ActionKey(6));
522 actionList.add(ab.build());
525 ab.setAction(ActionUtils.outputAction(
526 FlowUtils.getSpecialNodeConnectorId(dataPathId, OutputPortValues.INPORT.toString())));
528 ab.setKey(new ActionKey(7));
529 actionList.add(ab.build());
531 // Create Apply Actions Instruction
532 aab.setAction(actionList);
533 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
535 ib.setKey(new InstructionKey(0));
536 instructions.add(ib.build());
538 isb.setInstruction(instructions);
539 flowBuilder.setInstructions(isb.build());
540 writeFlow(flowBuilder, nodeBuilder);
542 removeFlow(flowBuilder, nodeBuilder);
546 private List<Action> getNshAction(NshUtils header, List<Action> actionList) {
547 // Build the Actions to Add the NSH Header
548 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
549 ActionUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
550 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC2Load =
551 ActionUtils.nxLoadNshc2RegAction(header.getNshMetaC2());
552 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nspLoad =
553 ActionUtils.nxSetNspAction(header.getNshNsp());
554 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nsiLoad =
555 ActionUtils.nxSetNsiAction(header.getNshNsi());
556 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
557 ActionUtils.nxLoadTunIdAction(BigInteger.valueOf(header.getNshNsp()), false);
558 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
559 ActionUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
561 int count = actionList.size();
562 actionList.add(new ActionBuilder()
563 .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC1Load).build());
564 //actionList.add(new ActionBuilder()
565 // .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC2Load).build());
566 actionList.add(new ActionBuilder()
567 .setKey(new ActionKey(count)).setOrder(count++).setAction(nspLoad).build());
568 actionList.add(new ActionBuilder()
569 .setKey(new ActionKey(count)).setOrder(count++).setAction(nsiLoad).build());
570 actionList.add(new ActionBuilder()
571 .setKey(new ActionKey(count)).setOrder(count++).setAction(loadChainTunDest).build());
572 actionList.add(new ActionBuilder()
573 .setKey(new ActionKey(count)).setOrder(count).setAction(loadChainTunVnid).build());
577 public MatchBuilder buildMatch(Matches matches) {
578 MatchBuilder matchBuilder = new MatchBuilder();
580 if (matches.getAceType() instanceof AceIp) {
581 AceIp aceIp = (AceIp)matches.getAceType();
582 if (aceIp.getAceIpVersion() instanceof AceIpv4) {
583 //AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
584 //MatchUtils.createSrcL3IPv4Match(matchBuilder, aceIpv4.getSourceIpv4Network());
585 //MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Network());
586 MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
587 MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
588 aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
590 MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
591 MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
592 aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
594 } else if (matches.getAceType() instanceof AceEth) {
595 AceEth aceEth = (AceEth) matches.getAceType();
596 MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(aceEth.getSourceMacAddress().getValue()));
597 MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(aceEth.getDestinationMacAddress().getValue()),
598 new MacAddress(aceEth.getDestinationMacAddressMask().getValue()));
601 LOG.info("buildMatch: {}", matchBuilder.build());