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