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