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