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