Added support for multiple Actions.
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / FlowUtils.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
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.GroupActionCaseBuilder;
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.SetDlDstActionCaseBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCaseBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpShaCaseBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpThaCaseBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIdCaseBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIpv4DstCaseBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpOpCaseBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpSpaCaseBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpTpaCaseBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfEthDstCaseBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputReg;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputRegBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoadBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.DstBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMoveBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.SrcBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.SrcChoice;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxArpShaCaseBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfArpSpaCaseBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthSrcCaseBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg1Key;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg2Key;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg3Key;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg4Key;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg5Key;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg6Key;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg7Key;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxTunIdKey;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.tun.id.grouping.NxmNxTunIdBuilder;
119 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
120
121 import com.google.common.collect.ImmutableList;
122 import com.google.common.net.InetAddresses;
123
124 /**
125  * Utilities for constructing OpenFlow flows
126  */
127 public final class FlowUtils {
128     /**
129      * ARP ethertype
130      */
131     public static final Long ARP = Long.valueOf(0x0806);
132     /**
133      * IPv4 ethertype
134      */
135     public static final Long IPv4 = Long.valueOf(0x0800);
136     /**
137      * IPv6 ethertype
138      */
139     public static final Long IPv6 = Long.valueOf(0x86DD);
140     
141     /**
142      * Creates an Instance Identifier (path) for node with specified id
143      *
144      * @param nodeId
145      * @return
146      */
147     public static final InstanceIdentifier<Node> 
148         createNodePath(final NodeId nodeId) {
149         return InstanceIdentifier.builder(Nodes.class)
150                 .child(Node.class, new NodeKey(nodeId))
151                 .build();
152     }
153
154     /**
155      * Creates a table path from a node ID and table ID
156      *
157      * @param nodeId the ID of the node
158      * @param tableId the ID of the table
159      * @return the {@link InstanceIdentifier<Table>}
160      */
161     public static final InstanceIdentifier<Table> 
162         createTablePath(final NodeId nodeId, 
163                         final short tableId) {
164         return createNodePath(nodeId).builder()
165                 .augmentation(FlowCapableNode.class)
166                 .child(Table.class, new TableKey(tableId))
167                 .build();
168     }
169     
170     /**
171      * Creates a group path from a node ID and group ID
172      *
173      * @param nodeId the Id of the node
174      * @param groupId the ID of the group table
175      * @return the {@link InstanceIdentifier<Group>}
176      */
177     public static final InstanceIdentifier<Group> 
178         createGroupPath(final NodeId nodeId, 
179                         final GroupId groupId) {
180         return createNodePath(nodeId).builder()
181                 .augmentation(FlowCapableNode.class)
182                 .child(Group.class, new GroupKey(groupId))
183                 .build();
184     }
185     /**
186      * Creates a group path from a node ID and group ID
187      *
188      * @param nodeId the Id of the node
189      * @param groupId the ID of the group table
190      * @param bucketId the ID of the bucket in the group table
191      * @return the {@link InstanceIdentifier<Bucket>}
192      */
193     public static final InstanceIdentifier<Bucket> 
194         createBucketPath(final NodeId nodeId, 
195                          final GroupId groupId,
196                          final BucketId bucketId) {
197         return createNodePath(nodeId).builder()
198                 .augmentation(FlowCapableNode.class)
199                 .child(Group.class, new GroupKey(groupId))
200                 .child(Buckets.class)
201                 .child(Bucket.class, new BucketKey(bucketId))
202                 .build();
203     }
204     
205     /**
206      * Creates a path for particular flow, by appending flow-specific information
207      * to table path.
208      *
209      * @param table
210      * @param flowKey
211      * @return
212      */
213     public static InstanceIdentifier<Flow> 
214             createFlowPath(final InstanceIdentifier<Table> table, 
215                            final FlowKey flowKey) {
216         return table.child(Flow.class, flowKey);
217     }
218     
219     /**
220      * Creates a path for particular flow, by appending flow-specific information
221      * to table path.
222      *
223      * @param table
224      * @param flowId
225      * @return
226      */
227     public static InstanceIdentifier<Flow> 
228             createFlowPath(final InstanceIdentifier<Table> table, 
229                            final FlowId flowId) {
230         return createFlowPath(table, new FlowKey(flowId));
231     }
232
233     public static Instructions gotoTableInstructions(short tableId) {
234         return new InstructionsBuilder()
235         .setInstruction(ImmutableList.of(new InstructionBuilder()
236             .setOrder(Integer.valueOf(0))
237             .setInstruction(gotoTableIns(tableId))
238             .build()))
239         .build();
240     }
241     
242     public static Instruction gotoTableIns(short tableId) {
243         return new GoToTableCaseBuilder()
244             .setGoToTable(new GoToTableBuilder()
245                 .setTableId(tableId)
246                 .build())
247             .build();
248     }
249
250     public static ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList(Action... actions) {
251         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
252             = new ArrayList<>();
253         int count = 0;
254         for (Action action : actions) {
255             alist.add(new ActionBuilder()
256             .setOrder(Integer.valueOf(count++))
257             .setAction(action)
258             .build());
259         }
260         return alist;
261     }
262     public static ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList(List<ActionBuilder> actions) {
263         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
264             = new ArrayList<>();
265         int count = 0;
266         for (ActionBuilder action : actions) {
267             alist.add(action
268             .setOrder(Integer.valueOf(count++))
269             .build());
270         }
271         return alist;
272     }
273     public static Instruction applyActionIns(Action... actions) {
274         return new ApplyActionsCaseBuilder()
275             .setApplyActions(new ApplyActionsBuilder()
276                 .setAction(actionList(actions))
277                 .build())
278             .build();
279     }
280     public static Instruction applyActionIns(List<ActionBuilder> actions) {
281         return new ApplyActionsCaseBuilder()
282             .setApplyActions(new ApplyActionsBuilder()
283                 .setAction(actionList(actions))
284                 .build())
285             .build();
286     }
287     public static Instructions instructions(Instruction... instructions) {
288         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction> ins
289             = new ArrayList<>();
290         int order = 0;
291         for (Instruction i : instructions) {
292             ins.add(new InstructionBuilder()
293                 .setOrder(order++)
294                 .setInstruction(i)
295                 .build());
296         }
297         return new InstructionsBuilder().setInstruction(ins).build();
298     }
299
300     public static Instructions dropInstructions() {
301         return instructions(applyActionIns(dropAction()));
302     }
303     
304     public static Action dropAction() {
305         return new DropActionCaseBuilder()
306             .setDropAction(new DropActionBuilder()
307                 .build())
308             .build();
309     }
310     
311     public static Action outputAction(NodeConnectorId id) {
312         return new OutputActionCaseBuilder()
313             .setOutputAction(new OutputActionBuilder()
314                 .setOutputNodeConnector(new Uri(id.getValue()))
315                 .build())
316             .build();
317     }
318
319     public static Action groupAction(Long id) {
320         return new GroupActionCaseBuilder()
321             .setGroupAction(new GroupActionBuilder()
322                 .setGroupId(id)
323                 .build())
324             .build();
325     }
326     
327     public static Action setDlSrcAction(MacAddress mac) {
328         return new SetDlSrcActionCaseBuilder()
329             .setSetDlSrcAction(new SetDlSrcActionBuilder()
330                 .setAddress(mac)
331                 .build())
332             .build();
333     }
334
335     public static Action setDlDstAction(MacAddress mac) {
336         return new SetDlDstActionCaseBuilder()
337             .setSetDlDstAction(new SetDlDstActionBuilder()
338                 .setAddress(mac)
339                 .build())
340             .build();
341     }
342
343     public static Action decNwTtlAction() {
344         return new DecNwTtlCaseBuilder()
345             .setDecNwTtl(new DecNwTtlBuilder()
346                 .build())
347             .build();
348     }
349
350     public static Action nxLoadRegAction(DstChoice dstChoice,
351                                          BigInteger value,
352                                          int endOffset,
353                                          boolean groupBucket) {
354         NxRegLoad r = new NxRegLoadBuilder()
355             .setDst(new DstBuilder()
356                 .setDstChoice(dstChoice)
357                 .setStart(Integer.valueOf(0))
358                 .setEnd(Integer.valueOf(endOffset))
359                 .build())
360             .setValue(value)
361             .build();
362         if (groupBucket) {
363             return new NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder()
364                 .setNxRegLoad(r).build();
365         } else {
366             return new NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder()
367                 .setNxRegLoad(r).build();
368         }
369     }
370
371     public static Action nxLoadRegAction(DstChoice dstChoice,
372                                          BigInteger value) {
373         return nxLoadRegAction(dstChoice, value, 31, false);
374     }
375
376     public static Action nxLoadRegAction(Class<? extends NxmNxReg> reg,
377                                          BigInteger value) {
378         return nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(reg).build(),
379                                value);
380     }
381     public static Action nxLoadTunIPv4Action(String ipAddress, 
382                                              boolean groupBucket) {
383         int ip = InetAddresses.coerceToInteger(InetAddresses.forString(ipAddress));
384         long ipl = ip & 0xffffffffL;
385         return nxLoadRegAction(new DstNxTunIpv4DstCaseBuilder()
386                                     .setNxTunIpv4Dst(Boolean.TRUE).build(),
387                                BigInteger.valueOf(ipl),
388                                31,
389                                groupBucket);
390     }
391
392     public static Action nxLoadArpOpAction(BigInteger value) {
393         return nxLoadRegAction(new DstOfArpOpCaseBuilder()
394             .setOfArpOp(Boolean.TRUE).build(), value, 15, false);
395     }
396
397     public static Action nxLoadArpShaAction(BigInteger value) {
398         return nxLoadRegAction(new DstNxArpShaCaseBuilder()
399             .setNxArpSha(Boolean.TRUE).build(), value, 47, false);
400     }
401
402     public static Action nxLoadArpSpaAction(BigInteger value) {
403         return nxLoadRegAction(new DstOfArpSpaCaseBuilder()
404             .setOfArpSpa(Boolean.TRUE).build(), value);
405     }
406
407     public static Action nxLoadArpSpaAction(String ipAddress) {
408         int ip = InetAddresses.coerceToInteger(InetAddresses.forString(ipAddress));
409         long ipl = ip & 0xffffffffL;
410         return nxLoadArpSpaAction(BigInteger.valueOf(ipl));
411     }
412
413     public static Action nxMoveRegAction(SrcChoice srcChoice,
414                                          DstChoice dstChoice,
415                                          int endOffset,
416                                          boolean groupBucket) {
417         NxRegMove r = new NxRegMoveBuilder()
418             .setSrc(new SrcBuilder()
419                 .setSrcChoice(srcChoice)
420                 .setStart(Integer.valueOf(0))
421                 .setEnd(Integer.valueOf(endOffset))
422                 .build())
423             .setDst(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.DstBuilder()
424                 .setDstChoice(dstChoice)
425                 .setStart(Integer.valueOf(0))
426                 .setEnd(Integer.valueOf(endOffset))
427                 .build())
428             .build();
429         if (groupBucket) {
430             return new NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder()
431                 .setNxRegMove(r).build();
432         } else {
433             return new NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder()
434                 .setNxRegMove(r).build();
435         }
436     }
437     
438     public static Action nxMoveRegAction(SrcChoice srcChoice,
439                                          DstChoice dstChoice) {
440         return nxMoveRegAction(srcChoice, dstChoice, 31, false);
441     }
442
443     public static Action nxMoveRegTunIdAction(Class<? extends NxmNxReg> src,
444                                               boolean groupBucket) {
445         return nxMoveRegAction(new SrcNxRegCaseBuilder()
446                                     .setNxReg(src).build(), 
447                                new DstNxTunIdCaseBuilder()
448                                    .setNxTunId(Boolean.TRUE).build(),
449                                31, 
450                                groupBucket);
451     }
452
453     public static Action nxMoveArpShaToArpThaAction() {
454         return nxMoveRegAction(new SrcNxArpShaCaseBuilder()
455                                    .setNxArpSha(Boolean.TRUE).build(),
456                                new DstNxArpThaCaseBuilder()
457                                    .setNxArpTha(Boolean.TRUE).build(),
458                                47, false);
459     }
460
461     public static Action nxMoveEthSrcToEthDstAction() {
462         return nxMoveRegAction(new SrcOfEthSrcCaseBuilder()
463                                    .setOfEthSrc(Boolean.TRUE).build(),
464                                new DstOfEthDstCaseBuilder()
465                                    .setOfEthDst(Boolean.TRUE).build(),
466                                47, false);
467     }
468
469     public static Action nxMoveArpSpaToArpTpaAction() {
470         return nxMoveRegAction(new SrcOfArpSpaCaseBuilder()
471                                    .setOfArpSpa(Boolean.TRUE).build(),
472                                new DstOfArpTpaCaseBuilder()
473                                    .setOfArpTpa(Boolean.TRUE).build());
474     }
475
476     public static Action nxOutputRegAction(SrcChoice srcChoice) {
477         NxOutputReg r = new NxOutputRegBuilder()
478             .setSrc(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.nx.output.reg.SrcBuilder()
479                 .setSrcChoice(srcChoice)
480                 .setOfsNbits(Integer.valueOf(31))
481                 .build())
482             .setMaxLen(Integer.valueOf(0xffff))
483             .build();
484         return new NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder()
485             .setNxOutputReg(r).build();
486     }
487
488     public static Action nxOutputRegAction(Class<? extends NxmNxReg> reg) {
489         return nxOutputRegAction(new SrcNxRegCaseBuilder().setNxReg(reg).build());
490     }
491
492     public static class RegMatch {
493         final Class<? extends NxmNxReg> reg;
494         final Long value;
495         public RegMatch(Class<? extends NxmNxReg> reg, Long value) {
496             super();
497             this.reg = reg;
498             this.value = value;
499         }
500         public static RegMatch of(Class<? extends NxmNxReg> reg, Long value) {
501             return new RegMatch(reg, value);
502         }
503     }
504     
505     public static void addNxRegMatch(MatchBuilder match,
506                                      RegMatch... matches) {
507         ArrayList<ExtensionList> extensions = new ArrayList<>();
508         for (RegMatch rm : matches) {
509             Class<? extends ExtensionKey> key;
510             if (NxmNxReg0.class.equals(rm.reg)) {
511                 key = NxmNxReg0Key.class;
512             } else if (NxmNxReg1.class.equals(rm.reg)) {
513                 key = NxmNxReg1Key.class;
514             } else if (NxmNxReg2.class.equals(rm.reg)) {
515                 key = NxmNxReg2Key.class;
516             } else if (NxmNxReg3.class.equals(rm.reg)) {
517                 key = NxmNxReg3Key.class;
518             } else if (NxmNxReg4.class.equals(rm.reg)) {
519                 key = NxmNxReg4Key.class;
520             } else if (NxmNxReg5.class.equals(rm.reg)) {
521                 key = NxmNxReg5Key.class;
522             } else if (NxmNxReg6.class.equals(rm.reg)) {
523                 key = NxmNxReg6Key.class;
524             } else {
525                 key = NxmNxReg7Key.class;
526             }
527             NxAugMatchNodesNodeTableFlow am = 
528                     new NxAugMatchNodesNodeTableFlowBuilder()
529                 .setNxmNxReg(new NxmNxRegBuilder()
530                     .setReg(rm.reg)
531                     .setValue(rm.value)
532                     .build())
533                 .build();
534             extensions.add(new ExtensionListBuilder()
535                 .setExtensionKey(key)
536                 .setExtension(new ExtensionBuilder()
537                      .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
538                      .build())
539                 .build());
540         }
541         GeneralAugMatchNodesNodeTableFlow m = 
542                 new GeneralAugMatchNodesNodeTableFlowBuilder()
543             .setExtensionList(extensions)
544             .build();
545         match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
546     }
547
548     public static void addNxTunIdMatch(MatchBuilder match,
549                                        int tunId) {
550         NxAugMatchNodesNodeTableFlow am = 
551                new NxAugMatchNodesNodeTableFlowBuilder()
552                    .setNxmNxTunId(new NxmNxTunIdBuilder()
553                        .setValue(BigInteger.valueOf(tunId))
554                        .build())
555                    .build();
556         GeneralAugMatchNodesNodeTableFlow m = 
557                 new GeneralAugMatchNodesNodeTableFlowBuilder()
558             .setExtensionList(ImmutableList.of(new ExtensionListBuilder()
559                 .setExtensionKey(NxmNxTunIdKey.class)
560                 .setExtension(new ExtensionBuilder()
561                     .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
562                     .build())
563                 .build()))
564             .build();
565         match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
566     }
567
568     public static EthernetMatch ethernetMatch(MacAddress srcMac, 
569                                               MacAddress dstMac,
570                                               Long etherType) {
571         EthernetMatchBuilder emb = new  EthernetMatchBuilder();
572         if (srcMac != null)
573             emb.setEthernetSource(new EthernetSourceBuilder()
574                 .setAddress(srcMac)
575                 .build());
576         if (dstMac != null)
577             emb.setEthernetDestination(new EthernetDestinationBuilder()
578                 .setAddress(dstMac)
579                 .build());
580         if (etherType != null)
581             emb.setEthernetType(new EthernetTypeBuilder()
582                 .setType(new EtherType(etherType))
583                 .build());
584         return emb.build();
585     }
586 }
587