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