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