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