Move utility function to common place.
[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.NxActionSetNsiNodesNodeTableFlowApplyActionsCaseBuilder;
93 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;
94 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.NxActionSetNspNodesNodeTableFlowApplyActionsCaseBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputReg;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputRegBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsi.grouping.NxSetNsi;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsi.grouping.NxSetNsiBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsp.grouping.NxSetNsp;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsp.grouping.NxSetNspBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoadBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.DstBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMoveBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.SrcBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.SrcChoice;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxArpShaCaseBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfArpSpaCaseBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthSrcCaseBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg1Key;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg2Key;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg3Key;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg4Key;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg5Key;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg6Key;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg7Key;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxTunIdKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNsiKey;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNspKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsi.grouping.NxmNxNsiBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsp.grouping.NxmNxNspBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.tun.id.grouping.NxmNxTunIdBuilder;
129 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
130
131 import com.google.common.collect.ImmutableList;
132 import com.google.common.net.InetAddresses;
133
134 /**
135  * Utilities for constructing OpenFlow flows
136  */
137 public final class FlowUtils {
138     /**
139      * ARP ethertype
140      */
141     public static final Long ARP = Long.valueOf(0x0806);
142     /**
143      * IPv4 ethertype
144      */
145     public static final Long IPv4 = Long.valueOf(0x0800);
146     /**
147      * IPv6 ethertype
148      */
149     public static final Long IPv6 = Long.valueOf(0x86DD);
150     
151     /**
152      * Creates an Instance Identifier (path) for node with specified id
153      *
154      * @param nodeId
155      * @return
156      */
157     public static final InstanceIdentifier<Node> 
158         createNodePath(final NodeId nodeId) {
159         return InstanceIdentifier.builder(Nodes.class)
160                 .child(Node.class, new NodeKey(nodeId))
161                 .build();
162     }
163
164     /**
165      * Creates a table path from a node ID and table ID
166      *
167      * @param nodeId the ID of the node
168      * @param tableId the ID of the table
169      * @return the {@link InstanceIdentifier<Table>}
170      */
171     public static final InstanceIdentifier<Table> 
172         createTablePath(final NodeId nodeId, 
173                         final short tableId) {
174         return createNodePath(nodeId).builder()
175                 .augmentation(FlowCapableNode.class)
176                 .child(Table.class, new TableKey(tableId))
177                 .build();
178     }
179     
180     /**
181      * Creates a group path from a node ID and group ID
182      *
183      * @param nodeId the Id of the node
184      * @param groupId the ID of the group table
185      * @return the {@link InstanceIdentifier<Group>}
186      */
187     public static final InstanceIdentifier<Group> 
188         createGroupPath(final NodeId nodeId, 
189                         final GroupId groupId) {
190         return createNodePath(nodeId).builder()
191                 .augmentation(FlowCapableNode.class)
192                 .child(Group.class, new GroupKey(groupId))
193                 .build();
194     }
195     /**
196      * Creates a group path from a node ID and group ID
197      *
198      * @param nodeId the Id of the node
199      * @param groupId the ID of the group table
200      * @param bucketId the ID of the bucket in the group table
201      * @return the {@link InstanceIdentifier<Bucket>}
202      */
203     public static final InstanceIdentifier<Bucket> 
204         createBucketPath(final NodeId nodeId, 
205                          final GroupId groupId,
206                          final BucketId bucketId) {
207         return createNodePath(nodeId).builder()
208                 .augmentation(FlowCapableNode.class)
209                 .child(Group.class, new GroupKey(groupId))
210                 .child(Buckets.class)
211                 .child(Bucket.class, new BucketKey(bucketId))
212                 .build();
213     }
214     
215     /**
216      * Creates a path for particular flow, by appending flow-specific information
217      * to table path.
218      *
219      * @param table
220      * @param flowKey
221      * @return
222      */
223     public static InstanceIdentifier<Flow> 
224             createFlowPath(final InstanceIdentifier<Table> table, 
225                            final FlowKey flowKey) {
226         return table.child(Flow.class, flowKey);
227     }
228     
229     /**
230      * Creates a path for particular flow, by appending flow-specific information
231      * to table path.
232      *
233      * @param table
234      * @param flowId
235      * @return
236      */
237     public static InstanceIdentifier<Flow> 
238             createFlowPath(final InstanceIdentifier<Table> table, 
239                            final FlowId flowId) {
240         return createFlowPath(table, new FlowKey(flowId));
241     }
242
243     public static Instructions gotoTableInstructions(short tableId) {
244         return new InstructionsBuilder()
245         .setInstruction(ImmutableList.of(new InstructionBuilder()
246             .setOrder(Integer.valueOf(0))
247             .setInstruction(gotoTableIns(tableId))
248             .build()))
249         .build();
250     }
251     
252     public static Instruction gotoTableIns(short tableId) {
253         return new GoToTableCaseBuilder()
254             .setGoToTable(new GoToTableBuilder()
255                 .setTableId(tableId)
256                 .build())
257             .build();
258     }
259
260     public static ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList(Action... actions) {
261         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
262             = new ArrayList<>();
263         int count = 0;
264         for (Action action : actions) {
265             alist.add(new ActionBuilder()
266             .setOrder(Integer.valueOf(count++))
267             .setAction(action)
268             .build());
269         }
270         return alist;
271     }
272     public static ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList(List<ActionBuilder> actions) {
273         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
274             = new ArrayList<>();
275         int count = 0;
276         for (ActionBuilder action : actions) {
277             alist.add(action
278             .setOrder(Integer.valueOf(count++))
279             .build());
280         }
281         return alist;
282     }
283     public static Instruction applyActionIns(Action... actions) {
284         return new ApplyActionsCaseBuilder()
285             .setApplyActions(new ApplyActionsBuilder()
286                 .setAction(actionList(actions))
287                 .build())
288             .build();
289     }
290     public static Instruction applyActionIns(List<ActionBuilder> actions) {
291         return new ApplyActionsCaseBuilder()
292             .setApplyActions(new ApplyActionsBuilder()
293                 .setAction(actionList(actions))
294                 .build())
295             .build();
296     }
297     public static Instructions instructions(Instruction... instructions) {
298         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction> ins
299             = new ArrayList<>();
300         int order = 0;
301         for (Instruction i : instructions) {
302             ins.add(new InstructionBuilder()
303                 .setOrder(order++)
304                 .setInstruction(i)
305                 .build());
306         }
307         return new InstructionsBuilder().setInstruction(ins).build();
308     }
309
310     public static Instructions dropInstructions() {
311         return instructions(applyActionIns(dropAction()));
312     }
313     
314     public static Action dropAction() {
315         return new DropActionCaseBuilder()
316             .setDropAction(new DropActionBuilder()
317                 .build())
318             .build();
319     }
320     
321     public static Action outputAction(NodeConnectorId id) {
322         return new OutputActionCaseBuilder()
323             .setOutputAction(new OutputActionBuilder()
324                 .setOutputNodeConnector(new Uri(id.getValue()))
325                 .build())
326             .build();
327     }
328
329     public static Action groupAction(Long id) {
330         return new GroupActionCaseBuilder()
331             .setGroupAction(new GroupActionBuilder()
332                 .setGroupId(id)
333                 .build())
334             .build();
335     }
336     
337     public static Action setDlSrcAction(MacAddress mac) {
338         return new SetDlSrcActionCaseBuilder()
339             .setSetDlSrcAction(new SetDlSrcActionBuilder()
340                 .setAddress(mac)
341                 .build())
342             .build();
343     }
344
345     public static Action setDlDstAction(MacAddress mac) {
346         return new SetDlDstActionCaseBuilder()
347             .setSetDlDstAction(new SetDlDstActionBuilder()
348                 .setAddress(mac)
349                 .build())
350             .build();
351     }
352
353     public static Action decNwTtlAction() {
354         return new DecNwTtlCaseBuilder()
355             .setDecNwTtl(new DecNwTtlBuilder()
356                 .build())
357             .build();
358     }
359
360     public static Action nxLoadRegAction(DstChoice dstChoice,
361                                          BigInteger value,
362                                          int endOffset,
363                                          boolean groupBucket) {
364         NxRegLoad r = new NxRegLoadBuilder()
365             .setDst(new DstBuilder()
366                 .setDstChoice(dstChoice)
367                 .setStart(Integer.valueOf(0))
368                 .setEnd(Integer.valueOf(endOffset))
369                 .build())
370             .setValue(value)
371             .build();
372         if (groupBucket) {
373             return new NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder()
374                 .setNxRegLoad(r).build();
375         } else {
376             return new NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder()
377                 .setNxRegLoad(r).build();
378         }
379     }
380
381     public static Action nxSetNsiAction(Short nsi) {
382         NxSetNsi newNsi = new NxSetNsiBuilder()
383                                   .setNsi(nsi)
384                                   .build();
385         return new NxActionSetNsiNodesNodeTableFlowApplyActionsCaseBuilder()
386                        .setNxSetNsi(newNsi)
387                        .build();
388     }
389
390     public static Action nxSetNspAction(Long nsp) {
391         NxSetNsp newNsp = new NxSetNspBuilder()
392                                   .setNsp(nsp)
393                                   .build();
394         return new NxActionSetNspNodesNodeTableFlowApplyActionsCaseBuilder()
395                        .setNxSetNsp(newNsp)
396                        .build();
397     }
398
399     public static Action nxLoadRegAction(DstChoice dstChoice,
400                                          BigInteger value) {
401         return nxLoadRegAction(dstChoice, value, 31, false);
402     }
403
404     public static Action nxLoadRegAction(Class<? extends NxmNxReg> reg,
405                                          BigInteger value) {
406         return nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(reg).build(),
407                                value);
408     }
409     public static Action nxLoadTunIPv4Action(String ipAddress, 
410                                              boolean groupBucket) {
411         int ip = InetAddresses.coerceToInteger(InetAddresses.forString(ipAddress));
412         long ipl = ip & 0xffffffffL;
413         return nxLoadRegAction(new DstNxTunIpv4DstCaseBuilder()
414                                     .setNxTunIpv4Dst(Boolean.TRUE).build(),
415                                BigInteger.valueOf(ipl),
416                                31,
417                                groupBucket);
418     }
419
420     public static Action nxLoadArpOpAction(BigInteger value) {
421         return nxLoadRegAction(new DstOfArpOpCaseBuilder()
422             .setOfArpOp(Boolean.TRUE).build(), value, 15, false);
423     }
424
425     public static Action nxLoadArpShaAction(BigInteger value) {
426         return nxLoadRegAction(new DstNxArpShaCaseBuilder()
427             .setNxArpSha(Boolean.TRUE).build(), value, 47, false);
428     }
429
430     public static Action nxLoadArpSpaAction(BigInteger value) {
431         return nxLoadRegAction(new DstOfArpSpaCaseBuilder()
432             .setOfArpSpa(Boolean.TRUE).build(), value);
433     }
434
435     public static Action nxLoadArpSpaAction(String ipAddress) {
436         int ip = InetAddresses.coerceToInteger(InetAddresses.forString(ipAddress));
437         long ipl = ip & 0xffffffffL;
438         return nxLoadArpSpaAction(BigInteger.valueOf(ipl));
439     }
440
441     public static Action nxMoveRegAction(SrcChoice srcChoice,
442                                          DstChoice dstChoice,
443                                          int endOffset,
444                                          boolean groupBucket) {
445         NxRegMove r = new NxRegMoveBuilder()
446             .setSrc(new SrcBuilder()
447                 .setSrcChoice(srcChoice)
448                 .setStart(Integer.valueOf(0))
449                 .setEnd(Integer.valueOf(endOffset))
450                 .build())
451             .setDst(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.DstBuilder()
452                 .setDstChoice(dstChoice)
453                 .setStart(Integer.valueOf(0))
454                 .setEnd(Integer.valueOf(endOffset))
455                 .build())
456             .build();
457         if (groupBucket) {
458             return new NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder()
459                 .setNxRegMove(r).build();
460         } else {
461             return new NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder()
462                 .setNxRegMove(r).build();
463         }
464     }
465     
466     public static Action nxMoveRegAction(SrcChoice srcChoice,
467                                          DstChoice dstChoice) {
468         return nxMoveRegAction(srcChoice, dstChoice, 31, false);
469     }
470
471     public static Action nxMoveRegTunIdAction(Class<? extends NxmNxReg> src,
472                                               boolean groupBucket) {
473         return nxMoveRegAction(new SrcNxRegCaseBuilder()
474                                     .setNxReg(src).build(), 
475                                new DstNxTunIdCaseBuilder()
476                                    .setNxTunId(Boolean.TRUE).build(),
477                                31, 
478                                groupBucket);
479     }
480
481     public static Action nxMoveArpShaToArpThaAction() {
482         return nxMoveRegAction(new SrcNxArpShaCaseBuilder()
483                                    .setNxArpSha(Boolean.TRUE).build(),
484                                new DstNxArpThaCaseBuilder()
485                                    .setNxArpTha(Boolean.TRUE).build(),
486                                47, false);
487     }
488
489     public static Action nxMoveEthSrcToEthDstAction() {
490         return nxMoveRegAction(new SrcOfEthSrcCaseBuilder()
491                                    .setOfEthSrc(Boolean.TRUE).build(),
492                                new DstOfEthDstCaseBuilder()
493                                    .setOfEthDst(Boolean.TRUE).build(),
494                                47, false);
495     }
496
497     public static Action nxMoveArpSpaToArpTpaAction() {
498         return nxMoveRegAction(new SrcOfArpSpaCaseBuilder()
499                                    .setOfArpSpa(Boolean.TRUE).build(),
500                                new DstOfArpTpaCaseBuilder()
501                                    .setOfArpTpa(Boolean.TRUE).build());
502     }
503
504     public static Action nxOutputRegAction(SrcChoice srcChoice) {
505         NxOutputReg r = new NxOutputRegBuilder()
506             .setSrc(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.nx.output.reg.SrcBuilder()
507                 .setSrcChoice(srcChoice)
508                 .setOfsNbits(Integer.valueOf(31))
509                 .build())
510             .setMaxLen(Integer.valueOf(0xffff))
511             .build();
512         return new NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder()
513             .setNxOutputReg(r).build();
514     }
515
516     public static Action nxOutputRegAction(Class<? extends NxmNxReg> reg) {
517         return nxOutputRegAction(new SrcNxRegCaseBuilder().setNxReg(reg).build());
518     }
519
520     public static class RegMatch {
521         final Class<? extends NxmNxReg> reg;
522         final Long value;
523         public RegMatch(Class<? extends NxmNxReg> reg, Long value) {
524             super();
525             this.reg = reg;
526             this.value = value;
527         }
528         public static RegMatch of(Class<? extends NxmNxReg> reg, Long value) {
529             return new RegMatch(reg, value);
530         }
531     }
532     
533     public static void addNxRegMatch(MatchBuilder match,
534                                      RegMatch... matches) {
535         ArrayList<ExtensionList> extensions = new ArrayList<>();
536         for (RegMatch rm : matches) {
537             Class<? extends ExtensionKey> key;
538             if (NxmNxReg0.class.equals(rm.reg)) {
539                 key = NxmNxReg0Key.class;
540             } else if (NxmNxReg1.class.equals(rm.reg)) {
541                 key = NxmNxReg1Key.class;
542             } else if (NxmNxReg2.class.equals(rm.reg)) {
543                 key = NxmNxReg2Key.class;
544             } else if (NxmNxReg3.class.equals(rm.reg)) {
545                 key = NxmNxReg3Key.class;
546             } else if (NxmNxReg4.class.equals(rm.reg)) {
547                 key = NxmNxReg4Key.class;
548             } else if (NxmNxReg5.class.equals(rm.reg)) {
549                 key = NxmNxReg5Key.class;
550             } else if (NxmNxReg6.class.equals(rm.reg)) {
551                 key = NxmNxReg6Key.class;
552             } else {
553                 key = NxmNxReg7Key.class;
554             }
555             NxAugMatchNodesNodeTableFlow am = 
556                     new NxAugMatchNodesNodeTableFlowBuilder()
557                 .setNxmNxReg(new NxmNxRegBuilder()
558                     .setReg(rm.reg)
559                     .setValue(rm.value)
560                     .build())
561                 .build();
562             extensions.add(new ExtensionListBuilder()
563                 .setExtensionKey(key)
564                 .setExtension(new ExtensionBuilder()
565                      .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
566                      .build())
567                 .build());
568         }
569         GeneralAugMatchNodesNodeTableFlow m = 
570                 new GeneralAugMatchNodesNodeTableFlowBuilder()
571             .setExtensionList(extensions)
572             .build();
573         match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
574     }
575
576     public static void addNxTunIdMatch(MatchBuilder match,
577                                        int tunId) {
578         NxAugMatchNodesNodeTableFlow am = 
579                new NxAugMatchNodesNodeTableFlowBuilder()
580                    .setNxmNxTunId(new NxmNxTunIdBuilder()
581                        .setValue(BigInteger.valueOf(tunId))
582                        .build())
583                    .build();
584         GeneralAugMatchNodesNodeTableFlow m = 
585                 new GeneralAugMatchNodesNodeTableFlowBuilder()
586             .setExtensionList(ImmutableList.of(new ExtensionListBuilder()
587                 .setExtensionKey(NxmNxTunIdKey.class)
588                 .setExtension(new ExtensionBuilder()
589                     .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
590                     .build())
591                 .build()))
592             .build();
593         match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
594     }
595
596     public static void addNxNsiMatch(MatchBuilder match,
597                                      short nsi) {
598         NxAugMatchNodesNodeTableFlow am =
599                 new NxAugMatchNodesNodeTableFlowBuilder()
600                     .setNxmNxNsi(new NxmNxNsiBuilder()
601                         .setNsi(nsi)
602                         .build())
603                     .build();
604         GeneralAugMatchNodesNodeTableFlow m =
605                 new GeneralAugMatchNodesNodeTableFlowBuilder()
606             .setExtensionList(ImmutableList.of(new ExtensionListBuilder()
607                 .setExtensionKey(NxmNxNsiKey.class)
608                 .setExtension(new ExtensionBuilder()
609                     .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
610                     .build())
611                 .build()))
612              .build();
613         match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
614     }
615
616     public static void addNxNspMatch(MatchBuilder match,
617                                      Long nsp) {
618         NxAugMatchNodesNodeTableFlow am =
619                 new NxAugMatchNodesNodeTableFlowBuilder()
620                     .setNxmNxNsp(new NxmNxNspBuilder()
621                         .setValue(nsp)
622                         .build())
623                     .build();
624         GeneralAugMatchNodesNodeTableFlow m =
625                 new GeneralAugMatchNodesNodeTableFlowBuilder()
626             .setExtensionList(ImmutableList.of(new ExtensionListBuilder()
627                 .setExtensionKey(NxmNxNspKey.class)
628                 .setExtension(new ExtensionBuilder()
629                     .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
630                     .build())
631                 .build()))
632             .build();
633         match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
634     }
635
636     public static EthernetMatch ethernetMatch(MacAddress srcMac, 
637                                               MacAddress dstMac,
638                                               Long etherType) {
639         EthernetMatchBuilder emb = new  EthernetMatchBuilder();
640         if (srcMac != null)
641             emb.setEthernetSource(new EthernetSourceBuilder()
642                 .setAddress(srcMac)
643                 .build());
644         if (dstMac != null)
645             emb.setEthernetDestination(new EthernetDestinationBuilder()
646                 .setAddress(dstMac)
647                 .build());
648         if (etherType != null)
649             emb.setEthernetType(new EthernetTypeBuilder()
650                 .setType(new EtherType(etherType))
651                 .build());
652         return emb.build();
653     }
654
655     /**
656      * Parse an OF port number from a node connector ID
657      * @param id the ID
658      * @return the port number
659      */
660     public static long getOfPortNum(NodeConnectorId id) {
661         String cnid = id.getValue();
662         int ci = cnid.lastIndexOf(':');
663         if (ci < 0 || (ci+1 >= cnid.length()))
664             throw new NumberFormatException("Invalid node connector ID " + cnid);
665         return Long.parseLong(cnid.substring(ci+1));
666     }
667 }
668