Update .gitreview for new repo
[netvirt.git] / utils / mdsal-openflow / src / main / java / org / opendaylight / ovsdb / utils / mdsal / openflow / InstructionUtils.java
1 /*
2  * Copyright (c) 2013 - 2016 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.utils.mdsal.openflow;
10
11 import static org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils.dropAction;
12
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
17
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCaseBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
79
80 public class InstructionUtils {
81     private static final Logger LOG = LoggerFactory.getLogger(InstructionUtils.class);
82     private static final int IPV4 = 0x8100;
83     private static final int MAX_LENGTH = 0xffff;
84
85     /**
86      * Create Send to Controller Reserved Port Instruction (packet_in)
87      *
88      * @param nodeName Uri Prefix, containing nodeConnectorType and dpId (aka NodeId)
89      * @param ib Map InstructionBuilder without any instructions
90      * @return ib Map InstructionBuilder with instructions
91      */
92     public static InstructionBuilder createSendToControllerInstructions(String nodeName, InstructionBuilder ib) {
93
94         List<Action> actionList = new ArrayList<>();
95         ActionBuilder ab = new ActionBuilder();
96
97         OutputActionBuilder output = new OutputActionBuilder();
98         output.setMaxLength(MAX_LENGTH);
99         NodeId nodeId = new NodeId(nodeName);
100         output.setOutputNodeConnector(new NodeConnectorId(nodeId.getValue() + ":"
101                 + OutputPortValues.CONTROLLER.toString()));
102         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
103         ab.setOrder(0);
104         ab.setKey(new ActionKey(0));
105         actionList.add(ab.build());
106
107         // Create an Apply Action
108         ApplyActionsBuilder aab = new ApplyActionsBuilder();
109         aab.setAction(actionList);
110
111         // Wrap our Apply Action in an Instruction
112         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
113
114         return ib;
115     }
116
117     /**
118      * Create NORMAL Reserved Port Instruction (packet_in)
119      *
120      * @param nodeName Uri Prefix, containing nodeConnectorType and dpId (aka NodeId)
121      * @param ib Map InstructionBuilder without any instructions
122      * @return ib Map InstructionBuilder with instructions
123      */
124
125     public static InstructionBuilder createNormalInstructions(String nodeName, InstructionBuilder ib) {
126
127         List<Action> actionList = new ArrayList<>();
128         ActionBuilder ab = new ActionBuilder();
129
130         OutputActionBuilder output = new OutputActionBuilder();
131         NodeId nodeId = new NodeId(nodeName);
132         output.setOutputNodeConnector(new NodeConnectorId(nodeId.getValue() + ":"
133                 + OutputPortValues.NORMAL.toString()));
134         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
135         ab.setOrder(0);
136         ab.setKey(new ActionKey(0));
137         actionList.add(ab.build());
138
139         // Create an Apply Action
140         ApplyActionsBuilder aab = new ApplyActionsBuilder();
141         aab.setAction(actionList);
142
143         // Wrap our Apply Action in an Instruction
144         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
145
146         return ib;
147     }
148
149     /**
150      * Create LOCAL Reserved Port Instruction
151      *
152      * @param ib Map InstructionBuilder without any instructions
153      * @param dpidLong Long the datapath ID of a switch/node
154      * @return ib Map InstructionBuilder with instructions
155      */
156     public static InstructionBuilder createLocalInstructions(InstructionBuilder ib, long dpidLong) {
157         List<Action> actionList = new ArrayList<>();
158         ActionBuilder ab = new ActionBuilder();
159
160         OutputActionBuilder output = new OutputActionBuilder();
161         output.setOutputNodeConnector(new NodeConnectorId("openflow:" + dpidLong + ":"
162                 + OutputPortValues.LOCAL.toString()));
163         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
164         ab.setOrder(0);
165         ab.setKey(new ActionKey(0));
166         actionList.add(ab.build());
167
168         // Create an Apply Action
169         ApplyActionsBuilder aab = new ApplyActionsBuilder();
170         aab.setAction(actionList);
171
172         // Wrap our Apply Action in an Instruction
173         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
174
175         return ib;
176     }
177
178     /**
179      * Create Output Port Instruction
180      *
181      * @param ib       Map InstructionBuilder without any instructions
182      * @param dpidLong Long the datapath ID of a switch/node
183      * @param port     Long representing a port on a switch/node
184      * @return ib InstructionBuilder Map with instructions
185      */
186     public static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
187
188         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
189         LOG.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ",
190                 dpidLong, port);
191
192         List<Action> actionList = new ArrayList<>();
193         ActionBuilder ab = new ActionBuilder();
194         OutputActionBuilder oab = new OutputActionBuilder();
195         oab.setOutputNodeConnector(ncid);
196
197         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
198         ab.setOrder(0);
199         ab.setKey(new ActionKey(0));
200         actionList.add(ab.build());
201
202         // Create an Apply Action
203         ApplyActionsBuilder aab = new ApplyActionsBuilder();
204         aab.setAction(actionList);
205         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
206
207         return ib;
208     }
209
210     /**
211      * add Output Port action to Instruction action list.
212      * This is use for flow with single output port actions.
213      * Flow with mutiple output port actions should use createOutputPortInstructions() method.
214      *
215      * @param ib       Map InstructionBuilder without any instructions
216      * @param dpidLong Long the datapath ID of a switch/node
217      * @param port     Long representing a port on a switch/node
218      * @return ib InstructionBuilder Map with instructions
219      */
220     public static InstructionBuilder addOutputPortInstructions(InstructionBuilder ib,
221             Long dpidLong, Long port,
222             List<Instruction> instructions) {
223         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
224         LOG.debug(
225                 "addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}",
226                 dpidLong, port, instructions);
227
228         List<Action> actionList = new ArrayList<>();
229         ActionBuilder ab = new ActionBuilder();
230
231         List<Action> existingActions;
232         if (instructions != null) {
233             for (Instruction in : instructions) {
234                 if (in.getInstruction() instanceof ApplyActionsCase) {
235                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
236                     actionList.addAll(existingActions);
237                 }
238             }
239         }
240
241         /* Create output action for this port*/
242         OutputActionBuilder oab = new OutputActionBuilder();
243         oab.setOutputNodeConnector(ncid);
244         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
245         ab.setOrder(actionList.size());
246         ab.setKey(new ActionKey(actionList.size()));
247         actionList.add(ab.build());
248
249         // Create an Apply Action
250         ApplyActionsBuilder aab = new ApplyActionsBuilder();
251         aab.setAction(actionList);
252         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
253
254         return ib;
255     }
256
257     /**
258      * Remove Output Port from Instruction
259      *
260      * @param ib       Map InstructionBuilder without any instructions
261      * @param dpidLong Long the datapath ID of a switch/node
262      * @param port     Long representing a port on a switch/node
263      * @return ib InstructionBuilder Map with instructions
264      */
265     public static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
266             Long dpidLong, Long port, List<Instruction> instructions) {
267
268         final NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
269         final Uri ncidUri = new Uri(ncid);
270         LOG.debug(
271                 "removeOutputPortFromInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}",
272                 dpidLong, port, instructions);
273
274         List<Action> actionList = new ArrayList<>();
275         ActionBuilder ab;
276
277         // Start of by locating actions that will have port removed, from the existing instructionList
278         //
279         List<Action> existingActions;
280         if (instructions != null) {
281             for (Instruction in : instructions) {
282                 if (in.getInstruction() instanceof ApplyActionsCase) {
283                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
284                     actionList.addAll(existingActions);
285                     break;
286                 }
287             }
288         }
289
290         int removedActionOrder = 0;
291         boolean isPortDeleted = false;
292         boolean removeFlow = true;
293
294         // Locate specific action that has the port to be removed. Then, take note on its action order
295         // and remove it from list, in addition to flag that it was found.
296         //
297         for (Action action : actionList) {
298             if (action.getAction() instanceof OutputActionCase) {
299                 OutputActionCase opAction = (OutputActionCase) action.getAction();
300                 if (opAction.getOutputAction().getOutputNodeConnector().equals(ncidUri)) {
301                     /* Find the output port in action list and remove */
302                     removedActionOrder = action.getOrder();
303                     actionList.remove(action);
304                     isPortDeleted = true;
305                     break;
306                 }
307             }
308         }
309
310         if (isPortDeleted) {
311             // Iterate through all actions in the modified list and adjust the order of
312             // the actions left behind. With that, all actions that have order higher than
313             // the action removed gets their value decremented by 1. Note that this iteration
314             // visits all entries to account for cases where the list order is not the same
315             // as the action's order.
316             //
317             for (int i = 0; i < actionList.size(); i++) {
318                 Action action = actionList.get(i);
319                 if (action.getOrder() > removedActionOrder) {
320                     /* Shift the action by rebuilding action, using adjusted order */
321                     ab = new ActionBuilder();
322                     ab.setAction(action.getAction());
323                     ab.setOrder(action.getOrder() - 1);
324                     ab.setKey(new ActionKey(action.getOrder() - 1));
325                     Action actionNewOrder = ab.build();
326                     actionList.remove(action);
327                     actionList.add(i, actionNewOrder);
328                 } else if (action.getOrder() == removedActionOrder) {
329                     // Sanity: implementation assumes no two actions have the same order
330                     //
331                     LOG.error("Found action with same order as the action removed for {}, order {} index {}: {}",
332                             ncid, removedActionOrder, i, action);
333                 }
334
335                 // If action refers to a port output, then flow should be preserved.
336                 // We do this, so that if we are only left with non-output port actions,
337                 // we still remove the flow
338                 //
339                 if (action.getAction() instanceof OutputActionCase) {
340                     removeFlow = false;
341                 }
342             }
343         } else {
344             // If port we are asked to delete is not found, this implementation will leave actions
345             // alone and not remove the flow, as long as a remaining OutputActionCase is found.
346             //
347             for (Action action : actionList) {
348                 if (action.getAction() instanceof OutputActionCase) {
349                     removeFlow = false;
350                     break;
351                 }
352             }
353         }
354
355         /* Put new action list in Apply Action instruction */
356         if (!removeFlow) {
357             ApplyActionsBuilder aab = new ApplyActionsBuilder();
358             aab.setAction(actionList);
359             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
360             LOG.debug("removeOutputPortFromInstructions() : applyAction {}", aab.build());
361             return false;
362         } else {
363             /* if all output ports are removed. Return true to indicate flow remove */
364             return true;
365         }
366     }
367
368     /**
369      * Create Set Vlan ID Instruction - This includes push vlan action, and set field -&gt; vlan vid action
370      *
371      * @param ib     Map InstructionBuilder without any instructions
372      * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
373      * @return ib Map InstructionBuilder with instructions
374      */
375     public static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
376
377         List<Action> actionList = new ArrayList<>();
378         ActionBuilder ab = new ActionBuilder();
379
380         /* First we push vlan header */
381         PushVlanActionBuilder vlan = new PushVlanActionBuilder();
382         vlan.setEthernetType(IPV4);
383         ab.setAction(new PushVlanActionCaseBuilder().setPushVlanAction(vlan.build()).build());
384         ab.setOrder(0);
385         actionList.add(ab.build());
386
387         /* Then we set vlan id value as vlanId */
388         SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
389         vl.setVlanId(vlanId);
390         ab = new ActionBuilder();
391         ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
392         ab.setOrder(1);
393         actionList.add(ab.build());
394         // Create an Apply Action
395         ApplyActionsBuilder aab = new ApplyActionsBuilder();
396         aab.setAction(actionList);
397
398         // Wrap our Apply Action in an Instruction
399         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
400
401         return ib;
402     }
403
404     /**
405      * Create Pop Vlan Instruction - this remove vlan header
406      *
407      * @param ib Map InstructionBuilder without any instructions
408      * @return ib Map InstructionBuilder with instructions
409      */
410     public static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) {
411
412         List<Action> actionList = new ArrayList<>();
413         ActionBuilder ab = new ActionBuilder();
414
415         PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder();
416         ab.setAction(new PopVlanActionCaseBuilder().setPopVlanAction(popVlanActionBuilder.build()).build());
417         ab.setOrder(0);
418         actionList.add(ab.build());
419
420         // Create an Apply Action
421         ApplyActionsBuilder aab = new ApplyActionsBuilder();
422         aab.setAction(actionList);
423
424         // Wrap our Apply Action in an Instruction
425         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
426
427         return ib;
428     }
429
430     /**
431      * Create Set IPv4 Source Instruction
432      *
433      * @param ib        Map InstructionBuilder without any instructions
434      * @param prefixsrc String containing an IPv4 prefix
435      * @return ib Map InstructionBuilder with instructions
436      */
437     public static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
438
439         List<Action> actionList = new ArrayList<>();
440         ActionBuilder ab = new ActionBuilder();
441
442         SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
443         Ipv4Builder ipsrc = new Ipv4Builder();
444         ipsrc.setIpv4Address(prefixsrc);
445         setNwsrcActionBuilder.setAddress(ipsrc.build());
446         ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
447         ab.setOrder(0);
448         ab.setKey(new ActionKey(0));
449         actionList.add(ab.build());
450
451         // Create an Apply Action
452         ApplyActionsBuilder aab = new ApplyActionsBuilder();
453         aab.setAction(actionList);
454
455         // Wrap our Apply Action in an Instruction
456         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
457
458         return ib;
459     }
460
461     /**
462      * Create Set IPv4 Destination Instruction
463      *
464      * @param ib        Map InstructionBuilder without any instructions
465      * @param prefixdst String containing an IPv4 prefix
466      * @param extraAction (optional) Additional action to be performed in actionList
467      * @return ib Map InstructionBuilder with instructions
468      */
469     public static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst,
470                                                              ActionBuilder extraAction) {
471
472         List<Action> actionList = new ArrayList<>();
473         ActionBuilder ab = new ActionBuilder();
474
475         SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
476         Ipv4Builder ipdst = new Ipv4Builder();
477         ipdst.setIpv4Address(prefixdst);
478         setNwDstActionBuilder.setAddress(ipdst.build());
479         ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
480         ab.setOrder(0);
481         ab.setKey(new ActionKey(0));
482         actionList.add(ab.build());
483
484         if (extraAction != null) {
485             extraAction.setOrder(1);
486             extraAction.setKey(new ActionKey(1));
487             actionList.add(extraAction.build());
488         }
489
490         // Create an Apply Action
491         ApplyActionsBuilder aab = new ApplyActionsBuilder();
492         aab.setAction(actionList);
493
494         // Wrap our Apply Action in an Instruction
495         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
496
497         return ib;
498     }
499
500     /**
501      * Create Drop Instruction
502      *
503      * @param ib Map InstructionBuilder without any instructions
504      * @return ib Map InstructionBuilder with instructions
505      */
506     public static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
507
508         DropActionBuilder dab = new DropActionBuilder();
509         DropAction dropAction = dab.build();
510         ActionBuilder ab = new ActionBuilder();
511         ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
512         ab.setOrder(0);
513         ab.setKey(new ActionKey(0));
514
515         // Add our drop action to a list
516         List<Action> actionList = new ArrayList<>();
517         actionList.add(ab.build());
518
519         // Create an Apply Action
520         ApplyActionsBuilder aab = new ApplyActionsBuilder();
521         aab.setAction(actionList);
522
523         // Wrap our Apply Action in an Instruction
524         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
525
526         return ib;
527     }
528
529     /**
530      * Create GOTO Table Instruction Builder
531      *
532      * @param ib      Map InstructionBuilder without any instructions
533      * @param tableId short representing a flow table ID short representing a flow table ID
534      * @return ib Map InstructionBuilder with instructions
535      */
536     public static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
537
538         GoToTableBuilder gttb = new GoToTableBuilder();
539         gttb.setTableId(tableId);
540
541         // Wrap our Apply Action in an InstructionBuilder
542         ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
543
544         return ib;
545     }
546
547     /**
548      * Create Set Tunnel ID Instruction Builder
549      *
550      * @param ib       Map InstructionBuilder without any instructions
551      * @param tunnelId BigInteger representing a tunnel ID
552      * @return ib Map InstructionBuilder with instructions
553      */
554     public static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
555
556         List<Action> actionList = new ArrayList<>();
557         ActionBuilder ab = new ActionBuilder();
558         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
559
560         // Build the Set Tunnel Field Action
561         TunnelBuilder tunnel = new TunnelBuilder();
562         tunnel.setTunnelId(tunnelId);
563         setFieldBuilder.setTunnel(tunnel.build());
564         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
565         ab.setOrder(0);
566         ab.setKey(new ActionKey(0));
567         actionList.add(ab.build());
568
569         ApplyActionsBuilder aab = new ApplyActionsBuilder();
570         aab.setAction(actionList);
571
572         // Wrap the Apply Action in an InstructionBuilder and return
573         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
574
575         return ib;
576     }
577
578     /**
579      * Create Set Source TCP Port Instruction
580      *
581      * @param ib      Map InstructionBuilder without any instructions
582      * @param tcpport Integer representing a source TCP port
583      * @return ib Map InstructionBuilder with instructions
584      */
585     public static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
586
587         List<Action> actionList = new ArrayList<>();
588         ActionBuilder ab = new ActionBuilder();
589         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
590
591         // Build the Destination TCP Port
592         PortNumber tcpsrcport = new PortNumber(tcpport);
593         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
594         tcpmatch.setTcpSourcePort(tcpsrcport);
595
596         setFieldBuilder.setLayer4Match(tcpmatch.build());
597         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
598         ab.setOrder(0);
599         ab.setKey(new ActionKey(0));
600         actionList.add(ab.build());
601
602         ApplyActionsBuilder aab = new ApplyActionsBuilder();
603         aab.setAction(actionList);
604         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
605
606         return ib;
607     }
608
609     /**
610      * Create Set Destination TCP Port Instruction
611      *
612      * @param ib      Map InstructionBuilder without any instructions
613      * @param tcpport Integer representing a source TCP port
614      * @return ib Map InstructionBuilder with instructions
615      */
616     public static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
617
618         List<Action> actionList = new ArrayList<>();
619         ActionBuilder ab = new ActionBuilder();
620         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
621
622         // Build the Destination TCP Port
623         PortNumber tcpdstport = new PortNumber(tcpport);
624         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
625         tcpmatch.setTcpDestinationPort(tcpdstport);
626
627         setFieldBuilder.setLayer4Match(tcpmatch.build());
628         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
629         ab.setOrder(0);
630         ab.setKey(new ActionKey(0));
631         actionList.add(ab.build());
632
633         ApplyActionsBuilder aab = new ApplyActionsBuilder();
634         aab.setAction(actionList);
635         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
636
637         return ib;
638     }
639
640     /**
641      * Create Set Source UDP Port Instruction
642      *
643      * @param ib      Map InstructionBuilder without any instructions
644      * @param udpport Integer representing a source UDP port
645      * @return ib Map InstructionBuilder with instructions
646      */
647     public static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
648
649         List<Action> actionList = new ArrayList<>();
650         ActionBuilder ab = new ActionBuilder();
651         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
652
653         // Build the Destination TCP Port
654         PortNumber udpsrcport = new PortNumber(udpport);
655         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
656         udpmatch.setUdpSourcePort(udpsrcport);
657
658         setFieldBuilder.setLayer4Match(udpmatch.build());
659         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
660         ab.setOrder(0);
661         ab.setKey(new ActionKey(0));
662         actionList.add(ab.build());
663
664         ApplyActionsBuilder aab = new ApplyActionsBuilder();
665         aab.setAction(actionList);
666         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
667
668         return ib;
669     }
670
671     /**
672      * Create Set Destination UDP Port Instruction
673      *
674      * @param ib      Map InstructionBuilder without any instructions
675      * @param udpport Integer representing a destination UDP port
676      * @return ib Map InstructionBuilder with instructions
677      */
678     public static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
679
680         List<Action> actionList = new ArrayList<>();
681         ActionBuilder ab = new ActionBuilder();
682         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
683
684         // Build the Destination TCP Port
685         PortNumber udpdstport = new PortNumber(udpport);
686         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
687         udpmatch.setUdpDestinationPort(udpdstport);
688
689         setFieldBuilder.setLayer4Match(udpmatch.build());
690         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
691         ab.setOrder(0);
692         ab.setKey(new ActionKey(0));
693         actionList.add(ab.build());
694
695         ApplyActionsBuilder aab = new ApplyActionsBuilder();
696         aab.setAction(actionList);
697         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
698
699         return ib;
700     }
701
702     /**
703      * Create Set ICMP Code Instruction
704      *
705      * @param ib   Map InstructionBuilder without any instructions
706      * @param code short repesenting an ICMP code
707      * @return ib Map InstructionBuilder with instructions
708      */
709
710     public static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
711
712         List<Action> actionList = new ArrayList<>();
713         ActionBuilder ab = new ActionBuilder();
714         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
715         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
716
717         // Build the ICMPv4 Code Match
718         icmpv4match.setIcmpv4Code(code);
719         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
720
721         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
722         ab.setOrder(0);
723         ab.setKey(new ActionKey(0));
724         actionList.add(ab.build());
725         ApplyActionsBuilder aab = new ApplyActionsBuilder();
726         aab.setAction(actionList);
727
728         // Wrap our Apply Action in an Instruction
729         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
730
731         return ib;
732     }
733
734     /**
735      * Create Set ICMP Code Instruction
736      *
737      * @param ib Map InstructionBuilder without any instructions
738      * @return ib Map InstructionBuilder with instructions
739      */
740     public static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
741
742         List<Action> actionList = new ArrayList<>();
743         ActionBuilder ab = new ActionBuilder();
744         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
745         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
746
747         // Build the ICMPv4 Code Match
748         icmpv4match.setIcmpv4Code(type);
749         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
750
751         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
752         ab.setOrder(0);
753         ab.setKey(new ActionKey(0));
754         actionList.add(ab.build());
755         ApplyActionsBuilder aab = new ApplyActionsBuilder();
756         aab.setAction(actionList);
757
758         // Wrap our Apply Action in an Instruction
759         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
760
761         return ib;
762     }
763
764     /**
765      * Create Decrement TTL Instruction
766      *
767      * @param ib Map InstructionBuilder without any instructions
768      * @return ib Map InstructionBuilder with instructions
769      */
770     public static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
771         DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
772         DecNwTtl decNwTtl = decNwTtlBuilder.build();
773         ActionBuilder ab = new ActionBuilder();
774         ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
775         ab.setOrder(0);
776         ab.setKey(new ActionKey(0));
777
778         // Add our drop action to a list
779         List<Action> actionList = new ArrayList<>();
780         actionList.add(ab.build());
781
782         // Create an Apply Action
783         ApplyActionsBuilder aab = new ApplyActionsBuilder();
784         aab.setAction(actionList);
785
786         // Wrap our Apply Action in an Instruction
787         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
788
789         return ib;
790     }
791
792     /**
793      * Set ARP_SHA Instructions
794      * @param ib Map InstructionBuilder
795      * @param macsrc the macsrc
796      * @return instructionbuilder with new instructions
797      */
798     public static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
799
800         List<Action> actionList = new ArrayList<>();
801         ActionBuilder ab = new ActionBuilder();
802
803         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
804         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
805         ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
806         arpsrc.setAddress(macsrc);
807         arpmatch.setArpSourceHardwareAddress(arpsrc.build());
808         setFieldBuilder.setLayer3Match(arpmatch.build());
809         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
810         ab.setOrder(0);
811         ab.setKey(new ActionKey(0));
812         actionList.add(ab.build());
813
814         ApplyActionsBuilder aab = new ApplyActionsBuilder();
815         aab.setAction(actionList);
816         // Wrap our Apply Action in an Instruction
817         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
818
819         return ib;
820     }
821
822     /**
823      * Set ARP_THA Instructions
824      * @param ib Map InstructionBuilder
825      * @param macdst the macdst
826      * @return instructionbuilder with new attributes
827      */
828     public static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
829
830         List<Action> actionList = new ArrayList<>();
831         ActionBuilder ab = new ActionBuilder();
832         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
833
834         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
835         ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
836         arpdst.setAddress(macdst);
837         setFieldBuilder.setLayer3Match(arpmatch.build());
838         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
839         ab.setOrder(0);
840         ab.setKey(new ActionKey(0));
841         actionList.add(ab.build());
842
843         ApplyActionsBuilder aab = new ApplyActionsBuilder();
844         aab.setAction(actionList);
845         // Wrap our Apply Action in an Instruction
846         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
847
848         return ib;
849     }
850
851     /**
852      * Set ARP_TPA Instructions
853      * @param ib Map InstructionBuilder
854      * @param dstiparp the dstiparp
855      * @return instructionbuilder with new attributes
856      */
857     public static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
858
859         List<Action> actionList = new ArrayList<>();
860         ActionBuilder ab = new ActionBuilder();
861         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
862
863         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
864         arpmatch.setArpTargetTransportAddress(dstiparp);
865         setFieldBuilder.setLayer3Match(arpmatch.build());
866         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
867         ab.setOrder(0);
868         ab.setKey(new ActionKey(0));
869         actionList.add(ab.build());
870
871         ApplyActionsBuilder aab = new ApplyActionsBuilder();
872         aab.setAction(actionList);
873         // Wrap our Apply Action in an Instruction
874         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
875
876         return ib;
877     }
878
879     /**
880      * Set ARP_SPA Instructions
881      * @param ib Map InstructionBuilder
882      * @param srciparp the srciparp
883      * @return instructionbuilder with new attributes
884      */
885     public static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
886
887         List<Action> actionList = new ArrayList<>();
888         ActionBuilder ab = new ActionBuilder();
889         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
890
891         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
892         arpmatch.setArpSourceTransportAddress(srciparp);
893         setFieldBuilder.setLayer3Match(arpmatch.build());
894         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
895         ab.setOrder(0);
896         ab.setKey(new ActionKey(0));
897         actionList.add(ab.build());
898
899         ApplyActionsBuilder aab = new ApplyActionsBuilder();
900         aab.setAction(actionList);
901         // Wrap our Apply Action in an Instruction
902         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
903
904         return ib;
905     }
906
907     /**
908      * Set the Tunnel EndpointIPv4 Source Address
909      * @param ib Map InstructionBuilder
910      * @param srcIp Ipv4Prefix source IP for the tunnel endpoint (TEP)
911      * @return instructionbuilder with new attributes
912      */
913     public static InstructionBuilder createTunnelIpv4SrcInstructions(InstructionBuilder ib, Ipv4Prefix srcIp) {
914
915         List<Action> actionList = new ArrayList<>();
916         ActionBuilder ab = new ActionBuilder();
917
918         // Build the tunnel endpoint source IPv4 address
919         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
920
921         // Add the new IPv4 object as the tunnel destination
922         TunnelIpv4MatchBuilder tunnelIpv4MatchBuilder = new TunnelIpv4MatchBuilder();
923         tunnelIpv4MatchBuilder.setTunnelIpv4Source(srcIp);
924         setFieldBuilder.setLayer3Match(tunnelIpv4MatchBuilder.build());
925
926         // Add the IPv4 tunnel src to the set_field value
927         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
928         ab.setOrder(0);
929         ab.setKey(new ActionKey(0));
930         actionList.add(ab.build());
931
932         // Resulting action is a per/flow src TEP (set_field:172.16.100.100->tun_src)
933         ApplyActionsBuilder aab = new ApplyActionsBuilder();
934         aab.setAction(actionList);
935         // Wrap our Apply Action in an Instruction
936         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
937
938         return ib;
939     }
940
941     /**
942      * Set the Tunnel EndpointIPv4 Destination Address
943      * @param ib Map InstructionBuilder
944      * @param dstIp Ipv4Prefix destination IP for the tunnel endpoint (TEP)
945      * @return instructionbuilder with new attributes
946      */
947     public static InstructionBuilder createTunnelIpv4DstInstructions(InstructionBuilder ib, Ipv4Prefix dstIp) {
948
949         List<Action> actionList = new ArrayList<>();
950         ActionBuilder ab = new ActionBuilder();
951
952         // Build the tunnel endpoint dst IPv4 address
953         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
954
955         // Add the new IPv4 object as the tunnel destination
956         TunnelIpv4MatchBuilder tunnelIpv4MatchBuilder = new TunnelIpv4MatchBuilder();
957         tunnelIpv4MatchBuilder.setTunnelIpv4Destination(dstIp);
958         setFieldBuilder.setLayer3Match(tunnelIpv4MatchBuilder.build());
959
960         // Add the IPv4 tunnel src to the set_field value
961         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
962         ab.setOrder(0);
963         ab.setKey(new ActionKey(0));
964         actionList.add(ab.build());
965
966         // Resulting action is a per/flow src TEP (set_field:172.16.100.100->tun_src)
967         ApplyActionsBuilder aab = new ApplyActionsBuilder();
968         aab.setAction(actionList);
969         // Wrap our Apply Action in an Instruction
970         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
971
972         return ib;
973     }
974
975     /**
976      * Set IPv4 Source Address Instructions
977      * @param ib Map InstructionBuilder
978      * @param metaData BigInteger representing the OpenFlow metadata
979      * @param metaDataMask  BigInteger representing the OpenFlow metadata mask
980      * @return instructionbuilder with new attributes
981      */
982     public static InstructionBuilder createMetadataInstructions(InstructionBuilder ib, BigInteger metaData, BigInteger metaDataMask) {
983
984         WriteMetadataBuilder aab = new WriteMetadataBuilder();
985         aab.setMetadata(metaData);
986         aab.setMetadataMask(metaDataMask);
987         ib.setInstruction(new WriteMetadataCaseBuilder().setWriteMetadata(aab.build()).build());
988
989         /**
990         *
991         * TODO Determine why the following fails serialization
992         * with a null value. Per the spec it is optional.
993         * The metadata match, the Flowmod works w/o an accompanying mask.
994         *
995         * if (metaDataMask != null) {
996         *    aab.setMetadataMask(metaDataMask);
997         * }
998         *
999         */
1000
1001         return ib;
1002     }
1003
1004     public static InstructionBuilder createDlSrcInstructions(InstructionBuilder ib, MacAddress macAddress) {
1005
1006         List<Action> actionList = new ArrayList<>();
1007         ActionBuilder ab = new ActionBuilder();
1008
1009         SetDlSrcActionBuilder dlSrcActionBuilder= new SetDlSrcActionBuilder();
1010
1011         dlSrcActionBuilder.setAddress(macAddress);
1012
1013         ab.setAction(new SetDlSrcActionCaseBuilder().setSetDlSrcAction(dlSrcActionBuilder.build()).build());
1014         ab.setOrder(0);
1015         ab.setKey(new ActionKey(0));
1016         actionList.add(ab.build());
1017
1018
1019         // Create an Apply Action
1020         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1021         aab.setAction(actionList);
1022
1023         // Wrap our Apply Action in an Instruction
1024         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1025
1026         return ib;
1027     }
1028
1029     public static InstructionBuilder createDlDstInstructions(InstructionBuilder ib, MacAddress macAddress) {
1030
1031         List<Action> actionList = new ArrayList<>();
1032         ActionBuilder ab = new ActionBuilder();
1033
1034         SetDlDstActionBuilder dlDstActionBuilder= new SetDlDstActionBuilder();
1035
1036         dlDstActionBuilder.setAddress(macAddress);
1037
1038         ab.setAction(new SetDlDstActionCaseBuilder().setSetDlDstAction(dlDstActionBuilder.build()).build());
1039         ab.setOrder(0);
1040         ab.setKey(new ActionKey(0));
1041         actionList.add(ab.build());
1042
1043         // Create an Apply Action
1044         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1045         aab.setAction(actionList);
1046
1047         // Wrap our Apply Action in an Instruction
1048         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1049
1050         return ib;
1051     }
1052
1053     public static List<Action>
1054                   actionList(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action... actions) {
1055
1056         List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
1057             = new ArrayList<>();
1058         int count = 0;
1059         for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action : actions) {
1060             alist.add(new ActionBuilder()
1061                 .setOrder(count)
1062                 .setKey(new ActionKey(count))
1063                 .setAction(action)
1064                 .build());
1065             count++;
1066         }
1067         return alist;
1068     }
1069
1070     public static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction
1071         applyActionIns(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action... actions) {
1072
1073         return new ApplyActionsCaseBuilder()
1074             .setApplyActions(new ApplyActionsBuilder()
1075                 .setAction(actionList(actions))
1076                 .build())
1077             .build();
1078     }
1079
1080     public static Instructions getInstructions(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction... instructions) {
1081         List<Instruction> ins
1082             = new ArrayList<>();
1083         int order = 0;
1084         for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction i : instructions) {
1085             ins.add(new InstructionBuilder()
1086                 .setOrder(order)
1087                 .setKey(new InstructionKey(order))
1088                 .setInstruction(i)
1089                 .build());
1090             order++;
1091         }
1092         return new InstructionsBuilder().setInstruction(ins).build();
1093     }
1094
1095     public static Instructions dropInstructions() {
1096         return getInstructions(applyActionIns(dropAction()));
1097     }
1098
1099     /**
1100      * Extracts the existing instructions (if any) from the flow.
1101      *
1102      * @param flow The flow.
1103      * @return The instructions in the flow (empty if none).
1104      */
1105     public static List<Instruction> extractExistingInstructions(Flow flow) {
1106         if (flow != null) {
1107             Instructions ins = flow.getInstructions();
1108             if (ins != null) {
1109                 return ins.getInstruction();
1110             }
1111         }
1112         return Collections.emptyList();
1113     }
1114
1115     /**
1116      * Configures the flow builder to have the single given instruction.
1117      *
1118      * @param flowBuilder The flow builder.
1119      * @param instruction The instruction.
1120      * @return The flow builder.
1121      */
1122     public static FlowBuilder setFlowBuilderInstruction(FlowBuilder flowBuilder, Instruction instruction) {
1123         flowBuilder.setInstructions(
1124                 new InstructionsBuilder()
1125                         .setInstruction(Collections.singletonList(instruction))
1126                         .build());
1127         return flowBuilder;
1128     }
1129
1130     /**
1131      * Get a list of Instructions containing Nicira extensions that can have
1132      * additional OF/OXM instructions added to the returned Instruction list
1133      * @param instructions org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instructions
1134      * @return instruction list that additional
1135      */
1136     public static List<Instruction> getInstructionList(
1137             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction... instructions) {
1138         List<Instruction> ins
1139                 = new ArrayList<>();
1140         int order = 0;
1141         for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction i : instructions) {
1142             ins.add(new InstructionBuilder()
1143                     .setOrder(order++)
1144                     .setInstruction(i)
1145                     .build());
1146         }
1147         return ins;
1148     }
1149
1150     /**
1151      * Create InstructionBuilder with apply action.
1152      *
1153      * @param aab the apply action Builder.
1154      * @param order the position of the instruction in the instruction list.
1155      * @param drop indicates whether it is a drop instruction.
1156      * @return the instruction builder.
1157      */
1158     public static InstructionBuilder createInstructionBuilder(ApplyActionsBuilder aab, int order, boolean drop) {
1159         InstructionBuilder ib = new InstructionBuilder();
1160         ib.setOrder(order);
1161         ib.setKey(new InstructionKey(order));
1162         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1163         if (drop) {
1164             InstructionUtils.createDropInstructions(ib);
1165         }
1166         return ib;
1167     }
1168 }