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