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