Merge "Avoid logging stacktraces for schema version mismatches"
[netvirt.git] / openstack / net-virt-sfc / impl / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / sfc / workaround / services / SfcClassifierService.java
1 /*
2  * Copyright © 2015 Red Hat, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services;
10
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.osgi.framework.BundleContext;
49 import org.osgi.framework.ServiceReference;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
54     private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
55     private static final short TABLE_0 = 0;
56     private static final short UDP_SHORT = 17;
57     private static int cookieCounter = 0;
58     private static final int FLOW_INGRESSCLASS = 1;
59     private static final int FLOW_SFINGRESS = 2;
60     private static final int FLOW_SFEGRESS = 3;
61     private static final int FLOW_SFARP = 4;
62     private static final int FLOW_EGRESSCLASS1 = 5;
63     private static final int FLOW_EGRESSCLASS2 = 6;
64     private static final int FLOW_SFCTABLE = 7;
65
66     public SfcClassifierService(Service service) {
67         super(service);
68     }
69
70     public SfcClassifierService() {
71         super(Service.SFC_CLASSIFIER);
72     }
73
74     @Override
75     public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
76         super.setDependencies(bundleContext.getServiceReference(ISfcClassifierService.class.getName()), this);
77     }
78
79     @Override
80     public void setDependencies(Object impl) {}
81
82     private BigInteger getCookie(int index) {
83         String indexString = new String().format("%02d0000000000%04d", index, cookieCounter++);
84         return new BigInteger(indexString, 16);
85     }
86
87     @Override
88     public void programIngressClassifier(long dataPathId, String ruleName, Matches matches,
89                                          NshUtils nshHeader, long vxGpeOfPort, boolean write) {
90         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
91         FlowBuilder flowBuilder = new FlowBuilder();
92
93         MatchBuilder matchBuilder = buildMatch(matches);
94         //flowBuilder.setMatch(matchBuilder.build());
95         flowBuilder.setMatch(MatchUtils.addNxRegMatch(
96                 matchBuilder,
97                 new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build());
98
99         String flowId = "sfcIngressClass_" + ruleName;// + "_" + nshHeader.getNshNsp();
100         flowBuilder.setId(new FlowId(flowId));
101         FlowKey key = new FlowKey(new FlowId(flowId));
102         flowBuilder.setBarrier(true);
103         flowBuilder.setTableId(getTable());
104         flowBuilder.setKey(key);
105         flowBuilder.setFlowName(flowId);
106         flowBuilder.setHardTimeout(0);
107         flowBuilder.setIdleTimeout(0);
108         flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_INGRESSCLASS)));
109         flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_INGRESSCLASS)));
110
111         if (write) {
112             ActionBuilder ab = new ActionBuilder();
113             List<Action> actionList = new ArrayList<>();
114
115             ab.setAction(ActionUtils.nxMoveTunIdtoNshc2());
116             ab.setOrder(actionList.size());
117             ab.setKey(new ActionKey(actionList.size()));
118             actionList.add(ab.build());
119
120             getNshAction(nshHeader, actionList);
121
122             ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
123             ab.setOrder(actionList.size());
124             ab.setKey(new ActionKey(actionList.size()));
125             actionList.add(ab.build());
126
127             ApplyActionsBuilder aab = new ApplyActionsBuilder();
128             aab.setAction(actionList);
129
130             InstructionBuilder ib = new InstructionBuilder();
131             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
132             ib.setOrder(0);
133             ib.setKey(new InstructionKey(0));
134             List<Instruction> instructions = Lists.newArrayList();
135             instructions.add(ib.build());
136
137             InstructionsBuilder isb = new InstructionsBuilder();
138             isb.setInstruction(instructions);
139             flowBuilder.setInstructions(isb.build());
140             writeFlow(flowBuilder, nodeBuilder);
141         } else {
142             removeFlow(flowBuilder, nodeBuilder);
143         }
144     }
145
146     @Override
147     public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
148         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
149         FlowBuilder flowBuilder = new FlowBuilder();
150
151         MatchBuilder matchBuilder = new MatchBuilder();
152         flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort).build());
153
154         String flowId = "sfcTable_" + vxGpeOfPort;
155         flowBuilder.setId(new FlowId(flowId));
156         FlowKey key = new FlowKey(new FlowId(flowId));
157         flowBuilder.setBarrier(true);
158         flowBuilder.setTableId(TABLE_0);
159         flowBuilder.setKey(key);
160         flowBuilder.setFlowName(flowId);
161         flowBuilder.setHardTimeout(0);
162         flowBuilder.setIdleTimeout(0);
163         flowBuilder.setPriority(1000);
164         flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_SFCTABLE)));
165         flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_SFCTABLE)));
166
167         if (write) {
168             InstructionsBuilder isb = new InstructionsBuilder();
169             List<Instruction> instructions = Lists.newArrayList();
170             InstructionBuilder ib =
171                     InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
172             ib.setOrder(0);
173             ib.setKey(new InstructionKey(0));
174             instructions.add(ib.build());
175
176             isb.setInstruction(instructions);
177             flowBuilder.setInstructions(isb.build());
178             writeFlow(flowBuilder, nodeBuilder);
179         } else {
180             removeFlow(flowBuilder, nodeBuilder);
181         }
182     }
183
184     @Override
185     public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
186                                          int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
187         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
188         FlowBuilder flowBuilder = new FlowBuilder();
189
190         MatchBuilder matchBuilder = new MatchBuilder();
191         MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
192         MatchUtils.addNxNspMatch(matchBuilder, nsp);
193         flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nsi).build());
194
195         String flowId = "sfcEgressClass1_" + vxGpeOfPort;
196         flowBuilder.setId(new FlowId(flowId));
197         FlowKey key = new FlowKey(new FlowId(flowId));
198         flowBuilder.setBarrier(true);
199         flowBuilder.setTableId(TABLE_0);
200         flowBuilder.setKey(key);
201         flowBuilder.setFlowName(flowId);
202         flowBuilder.setHardTimeout(0);
203         flowBuilder.setIdleTimeout(0);
204         flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_EGRESSCLASS1)));
205         flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_EGRESSCLASS1)));
206
207         if (write) {
208             InstructionsBuilder isb = new InstructionsBuilder();
209             List<Instruction> instructions = Lists.newArrayList();
210             InstructionBuilder ib = new InstructionBuilder();
211
212             /*List<Action> actionList = Lists.newArrayList();
213
214             ActionBuilder ab = new ActionBuilder();
215             ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
216             ab.setOrder(0);
217             ab.setKey(new ActionKey(0));
218             actionList.add(ab.build());
219
220             ApplyActionsBuilder aab = new ApplyActionsBuilder();
221             aab.setAction(actionList);
222             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
223
224             ib.setOrder(instructions.size());
225             ib.setKey(new InstructionKey(instructions.size()));
226             instructions.add(ib.build());*/
227
228             ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
229             ib.setOrder(instructions.size());
230             ib.setKey(new InstructionKey(instructions.size()));
231             instructions.add(ib.build());
232
233             isb.setInstruction(instructions);
234             flowBuilder.setInstructions(isb.build());
235             writeFlow(flowBuilder, nodeBuilder);
236         } else {
237             removeFlow(flowBuilder, nodeBuilder);
238         }
239     }
240
241     // add 3: same match, add in_port sf, priority=40k, move c2 to tun_id, reg0-1, nsp=0,nsi=0
242     @Override
243     public void programEgressClassifier2(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
244                                          int tunnelOfPort, int tunnelId, boolean write) {
245         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
246         FlowBuilder flowBuilder = new FlowBuilder();
247
248         MatchBuilder matchBuilder = new MatchBuilder();
249         MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
250         MatchUtils.addNxRegMatch(matchBuilder,
251                 new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build();
252         MatchUtils.addNxNspMatch(matchBuilder, nsp);
253         flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nsi).build());
254
255         String flowId = "sfcEgressClass2_" + vxGpeOfPort;
256         flowBuilder.setId(new FlowId(flowId));
257         FlowKey key = new FlowKey(new FlowId(flowId));
258         flowBuilder.setBarrier(true);
259         flowBuilder.setTableId(getTable());
260         flowBuilder.setKey(key);
261         flowBuilder.setFlowName(flowId);
262         flowBuilder.setHardTimeout(0);
263         flowBuilder.setIdleTimeout(0);
264         flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_EGRESSCLASS2)));
265         flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_EGRESSCLASS2)));
266
267         if (write) {
268             InstructionsBuilder isb = new InstructionsBuilder();
269             List<Instruction> instructions = Lists.newArrayList();
270             List<Action> actionList = Lists.newArrayList();
271
272             ActionBuilder ab = new ActionBuilder();
273
274             // don't do this, need it to match on the resubmit side and get past table 10 so it isn't reclassified
275             //ab.setAction(ActionUtils.nxSetNspAction((long)(0)));
276             //ab.setOrder(0);
277             //ab.setKey(new ActionKey(0));
278             //actionList.add(ab.build());
279
280             ab.setAction(ActionUtils.nxResubmitAction(tunnelOfPort, TABLE_0));
281             ab.setOrder(actionList.size());
282             ab.setKey(new ActionKey(actionList.size()));
283             actionList.add(ab.build());
284
285             ApplyActionsBuilder aab = new ApplyActionsBuilder();
286             aab.setAction(actionList);
287             InstructionBuilder ib = new InstructionBuilder();
288             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
289
290             ib.setOrder(0);
291             ib.setKey(new InstructionKey(0));
292             instructions.add(ib.build());
293
294             isb.setInstruction(instructions);
295             flowBuilder.setInstructions(isb.build());
296             writeFlow(flowBuilder, nodeBuilder);
297
298         } else {
299             removeFlow(flowBuilder, nodeBuilder);
300         }
301     }
302
303     // packet from sf to sff that need to go out local
304     @Override
305     public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
306         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
307         FlowBuilder flowBuilder = new FlowBuilder();
308
309         MatchBuilder matchBuilder = new MatchBuilder();
310         MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
311         MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
312         flowBuilder.setMatch(MatchUtils.addNxRegMatch(
313                 matchBuilder, new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build());
314
315         String flowId = "sfEgress_" + dstPort;
316         flowBuilder.setId(new FlowId(flowId));
317         FlowKey key = new FlowKey(new FlowId(flowId));
318         flowBuilder.setBarrier(true);
319         flowBuilder.setTableId(getTable());
320         flowBuilder.setKey(key);
321         flowBuilder.setFlowName(flowId);
322         flowBuilder.setHardTimeout(0);
323         flowBuilder.setIdleTimeout(0);
324         flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_SFEGRESS)));
325         flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_SFEGRESS)));
326
327         if (write) {
328             InstructionBuilder ib = new InstructionBuilder();
329             InstructionsBuilder isb = new InstructionsBuilder();
330             List<Instruction> instructions = Lists.newArrayList();
331             InstructionUtils.createLocalInstructions(ib, dataPathId);
332             ib.setOrder(0);
333             ib.setKey(new InstructionKey(0));
334             instructions.add(ib.build());
335
336             isb.setInstruction(instructions);
337             flowBuilder.setInstructions(isb.build());
338             writeFlow(flowBuilder, nodeBuilder);
339         } else {
340             removeFlow(flowBuilder, nodeBuilder);
341         }
342     }
343
344     // looped back sff to sf packets
345     @Override
346     public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
347                                   String ipAddress, String sfDplName, boolean write) {
348         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
349         FlowBuilder flowBuilder = new FlowBuilder();
350
351         MatchBuilder matchBuilder = new MatchBuilder();
352         MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
353         Ipv4Prefix ipCidr = MatchUtils.iPv4PrefixFromIPv4Address(ipAddress);
354         MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(ipCidr));
355         flowBuilder.setMatch(MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort).build());
356
357         String flowId = "sfIngress_" + dstPort + "_" + ipAddress;
358         flowBuilder.setId(new FlowId(flowId));
359         FlowKey key = new FlowKey(new FlowId(flowId));
360         flowBuilder.setBarrier(true);
361         flowBuilder.setTableId(TABLE_0);
362         flowBuilder.setKey(key);
363         flowBuilder.setFlowName(flowId);
364         flowBuilder.setHardTimeout(0);
365         flowBuilder.setIdleTimeout(0);
366         flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_SFINGRESS)));
367         flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_SFINGRESS)));
368
369         if (write) {
370             InstructionBuilder ib = new InstructionBuilder();
371             InstructionsBuilder isb = new InstructionsBuilder();
372             List<Instruction> instructions = Lists.newArrayList();
373             InstructionUtils.createOutputPortInstructions(ib, dataPathId, sfOfPort);
374
375             ib.setOrder(0);
376             ib.setKey(new InstructionKey(0));
377             instructions.add(ib.build());
378
379             isb.setInstruction(instructions);
380             flowBuilder.setInstructions(isb.build());
381             writeFlow(flowBuilder, nodeBuilder);
382         } else {
383             removeFlow(flowBuilder, nodeBuilder);
384         }
385     }
386
387     @Override
388     public void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
389                                       String ipAddress, boolean write) {
390         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
391         FlowBuilder flowBuilder = new FlowBuilder();
392
393         MacAddress macAddress = new MacAddress(macAddressStr);
394
395         MatchBuilder matchBuilder = new MatchBuilder();
396         MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(Constants.ARP_ETHERTYPE));
397         MatchUtils.createArpDstIpv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress));
398         flowBuilder.setMatch(matchBuilder.build());
399
400         String flowId = "ArpResponder_" + ipAddress;
401         flowBuilder.setId(new FlowId(flowId));
402         FlowKey key = new FlowKey(new FlowId(flowId));
403         flowBuilder.setBarrier(true);
404         flowBuilder.setTableId(TABLE_0);
405         flowBuilder.setKey(key);
406         flowBuilder.setPriority(1024);
407         flowBuilder.setFlowName(flowId);
408         flowBuilder.setHardTimeout(0);
409         flowBuilder.setIdleTimeout(0);
410         flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_SFARP)));
411         flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_SFARP)));
412
413         if (write == true) {
414             InstructionBuilder ib = new InstructionBuilder();
415             InstructionsBuilder isb = new InstructionsBuilder();
416             List<Instruction> instructions = Lists.newArrayList();
417             ApplyActionsBuilder aab = new ApplyActionsBuilder();
418             ActionBuilder ab = new ActionBuilder();
419             List<Action> actionList = Lists.newArrayList();
420
421             // Move Eth Src to Eth Dst
422             ab.setAction(ActionUtils.nxMoveEthSrcToEthDstAction());
423             ab.setOrder(0);
424             ab.setKey(new ActionKey(0));
425             actionList.add(ab.build());
426
427             // Set Eth Src
428             ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
429             ab.setOrder(1);
430             ab.setKey(new ActionKey(1));
431             actionList.add(ab.build());
432
433             // Set ARP OP
434             ab.setAction(ActionUtils.nxLoadArpOpAction(BigInteger.valueOf(0x02L)));
435             ab.setOrder(2);
436             ab.setKey(new ActionKey(2));
437             actionList.add(ab.build());
438
439             // Move ARP SHA to ARP THA
440             ab.setAction(ActionUtils.nxMoveArpShaToArpThaAction());
441             ab.setOrder(3);
442             ab.setKey(new ActionKey(3));
443             actionList.add(ab.build());
444
445             // Move ARP SPA to ARP TPA
446             ab.setAction(ActionUtils.nxMoveArpSpaToArpTpaAction());
447             ab.setOrder(4);
448             ab.setKey(new ActionKey(4));
449             actionList.add(ab.build());
450
451             // Load Mac to ARP SHA
452             ab.setAction(ActionUtils.nxLoadArpShaAction(macAddress));
453             ab.setOrder(5);
454             ab.setKey(new ActionKey(5));
455             actionList.add(ab.build());
456
457             // Load IP to ARP SPA
458             ab.setAction(ActionUtils.nxLoadArpSpaAction(ipAddress));
459             ab.setOrder(6);
460             ab.setKey(new ActionKey(6));
461             actionList.add(ab.build());
462
463             // Output of InPort
464             ab.setAction(ActionUtils.outputAction(
465                     FlowUtils.getSpecialNodeConnectorId(dataPathId, OutputPortValues.INPORT.toString())));
466             ab.setOrder(7);
467             ab.setKey(new ActionKey(7));
468             actionList.add(ab.build());
469
470             // Create Apply Actions Instruction
471             aab.setAction(actionList);
472             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
473             ib.setOrder(0);
474             ib.setKey(new InstructionKey(0));
475             instructions.add(ib.build());
476
477             isb.setInstruction(instructions);
478             flowBuilder.setInstructions(isb.build());
479             writeFlow(flowBuilder, nodeBuilder);
480         } else {
481             removeFlow(flowBuilder, nodeBuilder);
482         }
483     }
484
485     private List<Action> getNshAction(NshUtils header, List<Action> actionList) {
486         // Build the Actions to Add the NSH Header
487         org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
488                 ActionUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
489         org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC2Load =
490                 ActionUtils.nxLoadNshc2RegAction(header.getNshMetaC2());
491         org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nspLoad =
492                 ActionUtils.nxSetNspAction(header.getNshNsp());
493         org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nsiLoad =
494                 ActionUtils.nxSetNsiAction(header.getNshNsi());
495         org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
496                 ActionUtils.nxLoadTunIdAction(BigInteger.valueOf(header.getNshNsp()), false);
497         org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
498                 ActionUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
499
500         int count = actionList.size();
501         actionList.add(new ActionBuilder()
502                 .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC1Load).build());
503         //actionList.add(new ActionBuilder()
504         // .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC2Load).build());
505         actionList.add(new ActionBuilder()
506                 .setKey(new ActionKey(count)).setOrder(count++).setAction(nspLoad).build());
507         actionList.add(new ActionBuilder()
508                 .setKey(new ActionKey(count)).setOrder(count++).setAction(nsiLoad).build());
509         actionList.add(new ActionBuilder()
510                 .setKey(new ActionKey(count)).setOrder(count++).setAction(loadChainTunDest).build());
511         actionList.add(new ActionBuilder()
512                 .setKey(new ActionKey(count)).setOrder(count).setAction(loadChainTunVnid).build());
513         return actionList;
514     }
515
516     public MatchBuilder buildMatch(Matches matches) {
517         MatchBuilder matchBuilder = new MatchBuilder();
518
519         if (matches.getAceType() instanceof AceIp) {
520             AceIp aceIp = (AceIp)matches.getAceType();
521             if (aceIp.getAceIpVersion() instanceof AceIpv4) {
522                 //AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
523                 //MatchUtils.createSrcL3IPv4Match(matchBuilder, aceIpv4.getSourceIpv4Network());
524                 //MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Network());
525                 MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
526                 MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
527                         aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
528             } else {
529                 MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
530                 MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
531                         aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
532             }
533         } else if (matches.getAceType() instanceof AceEth) {
534             AceEth aceEth = (AceEth) matches.getAceType();
535             MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(aceEth.getSourceMacAddress().getValue()));
536             MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(aceEth.getDestinationMacAddress().getValue()),
537                     new MacAddress(aceEth.getDestinationMacAddressMask().getValue()));
538         }
539
540         LOG.info("buildMatch: {}", matchBuilder.build());
541         return matchBuilder;
542     }
543 }