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