Bump mdsal version to 4.0.0
[netvirt.git] / sfc / classifier / impl / src / test / java / org / opendaylight / netvirt / sfc / classifier / providers / OpenFlow13ProviderTest.java
1 /*
2  * Copyright © 2017 Ericsson, 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.netvirt.sfc.classifier.providers;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.junit.Assert.fail;
16
17 import com.google.common.net.InetAddresses;
18 import java.util.List;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.opendaylight.genius.mdsalutil.NwConstants;
22 import org.opendaylight.netvirt.sfc.classifier.utils.AclMatches;
23 import org.opendaylight.netvirt.sfc.classifier.utils.OpenFlow13Utils;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.MatchesBuilder;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc1Case;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc2Case;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc4Case;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNsiCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNspCase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIdCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIpv4DstCase;
51 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.NxActionDecapNodesNodeTableFlowApplyActionsCase;
52 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.NxActionEncapNodesNodeTableFlowApplyActionsCase;
53 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.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
54 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.NxActionRegMoveNodesNodeTableFlowApplyActionsCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNodesNodeTableFlowWriteActionsCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc1Case;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc2Case;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc4Case;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNsiCase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNspCase;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIdCase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
64 import org.opendaylight.yangtools.yang.common.Empty;
65
66
67 public class OpenFlow13ProviderTest {
68
69     private OpenFlow13Provider openflowProvider;
70     private final NodeId nodeId;
71     private static final String NODE_ID_STR = "openflow:1234";
72     private static final String SFF_IP_STR = "192.168.0.1";
73     private static final Long IN_PORT = 8L;
74     private static final Long OUT_PORT = 12L;
75     private static final Long NSP = 6500L;
76     private static final Short NSI = (short) 255;
77     private static final Short EGRESS_NSI = (short) 253;
78
79     public OpenFlow13ProviderTest() {
80         nodeId = new NodeId(NODE_ID_STR);
81     }
82
83     @Before
84     public void setUp() {
85         openflowProvider = new OpenFlow13Provider();
86     }
87
88     @Test
89     public void createIngressClassifierFilterTunnelNshFlow() {
90         Flow flow = openflowProvider.createIngressClassifierFilterTunnelNshFlow(nodeId);
91
92         assertEquals(flow.getTableId().shortValue(), NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE);
93         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NSH_TUN_PRIORITY);
94         assertEquals(flow.getId().getValue(),
95                 OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NSH_TUN_FLOW_NAME + nodeId.getValue());
96         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_COOKIE);
97
98         checkMatchPacketType(flow.getMatch(), OpenFlow13Utils.PACKET_TYPE_NSH);
99
100         assertEquals(1, flow.getInstructions().getInstruction().size());
101         checkActionResubmit(flow.getInstructions().getInstruction().get(0).getInstruction(),
102                 NwConstants.SFC_TRANSPORT_INGRESS_TABLE);
103     }
104
105     @Test
106     public void createIngressClassifierFilterEthNshFlow() {
107         Flow flow = openflowProvider.createIngressClassifierFilterEthNshFlow(nodeId);
108
109         assertEquals(flow.getTableId().shortValue(), NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE);
110         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NSH_PRIORITY);
111         assertEquals(flow.getId().getValue(),
112                 OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_ETH_NSH_FLOW_NAME + nodeId.getValue());
113         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_COOKIE);
114
115         checkMatchEthNsh(flow.getMatch());
116         checkMatchTunDstIp(flow.getMatch(), OpenFlow13Provider.NULL_IP);
117
118         assertEquals(1, flow.getInstructions().getInstruction().size());
119         checkActionResubmit(flow.getInstructions().getInstruction().get(0).getInstruction(),
120                 NwConstants.LPORT_DISPATCHER_TABLE);
121     }
122
123     @Test
124     public void createIngressClassifierFilterNshFlow() {
125         Flow flow = openflowProvider.createIngressClassifierFilterNshFlow(nodeId);
126
127         assertEquals(flow.getTableId().shortValue(), NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE);
128         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NSH_PRIORITY);
129         assertEquals(flow.getId().getValue(),
130                 OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NSH_FLOW_NAME + nodeId.getValue());
131         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_COOKIE);
132
133         checkMatchPacketType(flow.getMatch(), OpenFlow13Utils.PACKET_TYPE_NSH);
134         checkMatchTunDstIp(flow.getMatch(), OpenFlow13Provider.NULL_IP);
135
136         assertEquals(1, flow.getInstructions().getInstruction().size());
137         checkActionResubmit(flow.getInstructions().getInstruction().get(0).getInstruction(),
138                 NwConstants.LPORT_DISPATCHER_TABLE);
139     }
140
141     @Test
142     public void createIngressClassifierFilterChainEgressFlow() {
143         Flow flow = openflowProvider.createIngressClassifierFilterChainEgressFlow(nodeId, NSP, EGRESS_NSI);
144
145         assertEquals(flow.getTableId().shortValue(), NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE);
146         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_CHAIN_EGRESS_PRIORITY);
147         assertEquals(flow.getId().getValue(),
148                 OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NSH_CHAIN_EGRESS_FLOW_NAME
149                         + nodeId.getValue() + "_" + NSP);
150         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_COOKIE);
151
152         checkMatchPacketType(flow.getMatch(), OpenFlow13Utils.PACKET_TYPE_NSH);
153         checkMatchNsp(flow.getMatch(), NSP);
154         checkMatchNsi(flow.getMatch(), EGRESS_NSI);
155
156         assertEquals(1, flow.getInstructions().getInstruction().size());
157         Instruction curInstruction = flow.getInstructions().getInstruction().get(0).getInstruction();
158         List<Action> actionList = checkApplyActionSize(curInstruction, 3);
159         checkActionMoveNsc4(actionList.get(0), true);
160         checkActionMoveReg(actionList.get(0), NxmNxReg6.class, 0, 31, false);
161         checkActionDecap(actionList.get(1));
162         checkActionResubmit(curInstruction, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE);
163     }
164
165     @Test
166     public void createIngressClassifierFilterNoNshFlow() {
167         Flow flow = openflowProvider.createIngressClassifierFilterNoNshFlow(nodeId);
168
169         assertEquals(flow.getTableId().shortValue(), NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE);
170         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NONSH_PRIORITY);
171         assertEquals(flow.getId().getValue(),
172                 OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NONSH_FLOW_NAME + nodeId.getValue());
173         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_COOKIE);
174
175         checkMatchEmpty(flow.getMatch());
176
177         assertEquals(1, flow.getInstructions().getInstruction().size());
178         checkActionGotoTable(flow.getInstructions().getInstruction().get(0).getInstruction(),
179                 NwConstants.INGRESS_SFC_CLASSIFIER_ACL_TABLE);
180     }
181
182     @Test
183     public void createIngressClassifierAclFlow() {
184         // Create an empty AclMatch to pass in
185         MatchesBuilder matchesBuilder = new MatchesBuilder();
186         matchesBuilder.setAceType(new AceIpBuilder().build());
187         AclMatches aclMatches = new AclMatches(matchesBuilder.build());
188
189         List<MatchBuilder> matchBuilds = aclMatches.buildMatch();
190
191         for (MatchBuilder matchBuilder : matchBuilds) {
192             Flow flow = openflowProvider.createIngressClassifierAclFlow(
193                     nodeId, matchBuilder, IN_PORT, NSP, NSI);
194
195             assertEquals(flow.getTableId().shortValue(), NwConstants.INGRESS_SFC_CLASSIFIER_ACL_TABLE);
196             assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_ACL_MATCH_PRIORITY);
197             assertEquals(flow.getId().getValue(),
198                     OpenFlow13Provider.INGRESS_CLASSIFIER_ACL_FLOW_NAME + "_" + nodeId.getValue()
199                     + matchBuilder.build().toString());
200             assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_ACL_COOKIE);
201
202             // Only checking the inport match, since the rest is tested in AclMatchesTest
203             checkMatchInport(flow.getMatch(), nodeId.getValue() + ":" + IN_PORT);
204
205             assertEquals(1, flow.getInstructions().getInstruction().size());
206             Instruction curInstruction = flow.getInstructions().getInstruction().get(0).getInstruction();
207             List<Action> actionList = checkApplyActionSize(curInstruction, 3);
208
209             checkActionLoadReg(actionList.get(0), NxmNxReg2.class, 8, 31, NSP);
210             checkActionLoadReg(actionList.get(1), NxmNxReg2.class, 0, 7, NSI);
211             checkActionResubmit(curInstruction, NwConstants.LPORT_DISPATCHER_TABLE);
212         }
213     }
214
215     @Test
216     public void createIngressClassifierAclNoMatchFlow() {
217         Flow flow = openflowProvider.createIngressClassifierAclNoMatchFlow(nodeId);
218
219         assertEquals(flow.getTableId().shortValue(), NwConstants.INGRESS_SFC_CLASSIFIER_ACL_TABLE);
220         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_ACL_NOMATCH_PRIORITY);
221         assertEquals(flow.getId().getValue(),
222                 OpenFlow13Provider.INGRESS_CLASSIFIER_ACL_FLOW_NAME + "_" + nodeId.getValue());
223         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_ACL_COOKIE);
224
225         checkMatchEmpty(flow.getMatch());
226
227         assertEquals(1, flow.getInstructions().getInstruction().size());
228         checkActionResubmit(flow.getInstructions().getInstruction().get(0).getInstruction(),
229                 NwConstants.LPORT_DISPATCHER_TABLE);
230     }
231
232     @Test
233     public void createEgressClassifierFilterNshFlow() {
234         Flow flow = openflowProvider.createEgressClassifierFilterNshFlow(nodeId);
235
236         assertEquals(flow.getTableId().shortValue(), NwConstants.EGRESS_SFC_CLASSIFIER_FILTER_TABLE);
237         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_FILTER_NSH_PRIORITY);
238         assertEquals(flow.getId().getValue(),
239                 OpenFlow13Provider.EGRESS_CLASSIFIER_FILTER_NSH_FLOW_NAME + nodeId.getValue());
240         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_FILTER_COOKIE);
241
242         checkMatchEmpty(flow.getMatch());
243
244         assertEquals(1, flow.getInstructions().getInstruction().size());
245         checkActionGotoTable(flow.getInstructions().getInstruction().get(0).getInstruction(),
246                 NwConstants.EGRESS_SFC_CLASSIFIER_NEXTHOP_TABLE);
247     }
248
249     @Test
250     public void createEgressClassifierFilterNoNshFlow() {
251         Flow flow = openflowProvider.createEgressClassifierFilterNoNshFlow(nodeId);
252
253         assertEquals(flow.getTableId().shortValue(), NwConstants.EGRESS_SFC_CLASSIFIER_FILTER_TABLE);
254         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_FILTER_NONSH_PRIORITY);
255         assertEquals(flow.getId().getValue(),
256                 OpenFlow13Provider.EGRESS_CLASSIFIER_FILTER_NONSH_FLOW_NAME + nodeId.getValue());
257         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_FILTER_COOKIE);
258
259         checkMatchReg(flow.getMatch(), NxmNxReg2.class, 0);
260
261         assertEquals(1, flow.getInstructions().getInstruction().size());
262         checkActionResubmit(flow.getInstructions().getInstruction().get(0).getInstruction(),
263                 NwConstants.EGRESS_LPORT_DISPATCHER_TABLE);
264     }
265
266     @Test
267     public void createEgressClassifierNextHopFlow() {
268         Flow flow = openflowProvider.createEgressClassifierNextHopFlow(nodeId);
269
270         assertEquals(flow.getTableId().shortValue(), NwConstants.EGRESS_SFC_CLASSIFIER_NEXTHOP_TABLE);
271         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_NEXTHOP_PRIORITY);
272         assertEquals(flow.getId().getValue(),
273                 OpenFlow13Provider.EGRESS_CLASSIFIER_NEXTHOP_FLOW_NAME + nodeId.getValue());
274         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_NEXTHOP_COOKIE);
275
276         checkMatchEmpty(flow.getMatch());
277
278         assertEquals(2, flow.getInstructions().getInstruction().size());
279         Instruction curInstruction = flow.getInstructions().getInstruction().get(0).getInstruction();
280         List<Action> actionList = checkApplyActionSize(curInstruction, 8);
281
282         checkActionEncap(actionList.get(0), OpenFlow13Utils.PACKET_TYPE_NSH);
283         checkActionMoveReg(actionList.get(1), NxmNxReg2.class, 8,31, true);
284         checkActionMoveNsp(actionList.get(1), false);
285         checkActionMoveReg(actionList.get(2), NxmNxReg2.class, 0,7, true);
286         checkActionMoveNsi(actionList.get(2), false);
287         checkActionLoadReg(actionList.get(3), NxmNxReg2.class, 0 , 31, 0);
288         checkActionMoveReg(actionList.get(4), NxmNxReg0.class, 0, 31, true);
289         checkActionMoveNsc1(actionList.get(4), false);
290         checkActionMoveTunId(actionList.get(5), true);
291         checkActionMoveNsc2(actionList.get(5), false);
292         checkActionMoveReg(actionList.get(6), NxmNxReg6.class, 0, 31, true);
293         checkActionMoveNsc4(actionList.get(6), false);
294         checkActionLoadTunId(actionList.get(7), OpenFlow13Provider.SFC_TUNNEL_ID);
295
296         curInstruction = flow.getInstructions().getInstruction().get(1).getInstruction();
297         checkActionGotoTable(curInstruction, NwConstants.EGRESS_SFC_CLASSIFIER_EGRESS_TABLE);
298     }
299
300     @Test
301     public void createEgressClassifierTransportEgressLocalFlow() {
302         Flow flow = openflowProvider.createEgressClassifierTransportEgressLocalFlow(nodeId, NSP);
303
304         assertEquals(flow.getTableId().shortValue(), NwConstants.EGRESS_SFC_CLASSIFIER_EGRESS_TABLE);
305         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_EGRESS_PRIORITY);
306         assertEquals(flow.getId().getValue(),
307                 OpenFlow13Provider.EGRESS_CLASSIFIER_TPORTEGRESS_FLOW_NAME + nodeId.getValue() + "_" + NSP);
308         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_TPORTEGRESS_COOKIE);
309
310         checkMatchPacketType(flow.getMatch(), OpenFlow13Utils.PACKET_TYPE_NSH);
311         checkMatchNsp(flow.getMatch(), NSP);
312
313         assertEquals(1, flow.getInstructions().getInstruction().size());
314         checkActionResubmit(flow.getInstructions().getInstruction().get(0).getInstruction(),
315                 NwConstants.SFC_TRANSPORT_INGRESS_TABLE);
316     }
317
318     @Test
319     public void createEgressClassifierTransportEgressRemoteNshFlow() {
320         Flow flow = openflowProvider.createEgressClassifierTransportEgressRemoteNshFlow(
321                 nodeId, NSP, OUT_PORT, SFF_IP_STR);
322
323         assertEquals(flow.getTableId().shortValue(), NwConstants.EGRESS_SFC_CLASSIFIER_EGRESS_TABLE);
324         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_EGRESS_PRIORITY);
325         assertEquals(flow.getId().getValue(),
326                 OpenFlow13Provider.EGRESS_CLASSIFIER_TPORTEGRESS_FLOW_NAME + nodeId.getValue() + "_" + NSP);
327         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_TPORTEGRESS_COOKIE);
328
329         checkMatchPacketType(flow.getMatch(), OpenFlow13Utils.PACKET_TYPE_NSH);
330         checkMatchNsp(flow.getMatch(), NSP);
331
332         assertEquals(1, flow.getInstructions().getInstruction().size());
333         List<Action> actionList = checkApplyActionSize(
334                 flow.getInstructions().getInstruction().get(0).getInstruction(), 2);
335
336         checkActionLoadTunIpv4(actionList.get(0), SFF_IP_STR);
337         checkActionOutport(actionList.get(1), "output:" + OUT_PORT);
338     }
339
340     @Test
341     public void createEgressClassifierTransportEgressRemoteEthNshFlow() {
342         Flow flow = openflowProvider.createEgressClassifierTransportEgressRemoteEthNshFlow(
343                 nodeId, NSP, OUT_PORT, SFF_IP_STR);
344
345         assertEquals(flow.getTableId().shortValue(), NwConstants.EGRESS_SFC_CLASSIFIER_EGRESS_TABLE);
346         assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_EGRESS_PRIORITY);
347         assertEquals(flow.getId().getValue(),
348                 OpenFlow13Provider.EGRESS_CLASSIFIER_TPORTEGRESS_FLOW_NAME + nodeId.getValue() + "_" + NSP);
349         assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.EGRESS_CLASSIFIER_TPORTEGRESS_COOKIE);
350
351         checkMatchPacketType(flow.getMatch(), OpenFlow13Utils.PACKET_TYPE_NSH);
352         checkMatchNsp(flow.getMatch(), NSP);
353
354         assertEquals(1, flow.getInstructions().getInstruction().size());
355         List<Action> actionList = checkApplyActionSize(
356                 flow.getInstructions().getInstruction().get(0).getInstruction(), 3);
357
358         checkActionEncap(actionList.get(0), OpenFlow13Utils.PACKET_TYPE_ETH);
359         checkActionLoadTunIpv4(actionList.get(1), SFF_IP_STR);
360         checkActionOutport(actionList.get(2), "output:" + OUT_PORT);
361     }
362
363     @Test
364     public void createIngressClassifierTunnelEthNshTrafficCaptureFlow() {
365         Flow flow = openflowProvider.createIngressClassifierTunnelEthNshTrafficCaptureFlow(nodeId);
366
367         assertEquals(flow.getTableId().shortValue(), NwConstants.INTERNAL_TUNNEL_TABLE);
368         assertEquals(flow.getPriority().intValue(),
369                 OpenFlow13Provider.INGRESS_CLASSIFIER_CAPTURE_SFC_TUNNEL_TRAFFIC_PRIORITY);
370         assertEquals(flow.getId().getValue(),
371                 OpenFlow13Provider.INGRESS_CLASSIFIER_CAPTURE_SFC_TUNNEL_ETH_NSH_TRAFFIC_FLOW_NAME + nodeId.getValue());
372         assertEquals(flow.getCookie().getValue(),
373                 OpenFlow13Provider.INGRESS_CLASSIFIER_CAPTURE_SFC_TUNNEL_TRAFFIC_COOKIE);
374
375         checkMatchEthNsh(flow.getMatch());
376         checkMatchTunId(flow.getMatch(), OpenFlow13Provider.SFC_TUNNEL_ID);
377
378         assertEquals(2, flow.getInstructions().getInstruction().size());
379         List<Action> actionList = checkApplyActionSize(
380                 flow.getInstructions().getInstruction().get(0).getInstruction(), 1);
381         checkActionDecap(actionList.get(0));
382         checkActionGotoTable(flow.getInstructions().getInstruction().get(1).getInstruction(),
383                 NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE);
384     }
385
386     @Test
387     public void createIngressClassifierTunnelNshTrafficCaptureFlow() {
388         Flow flow = openflowProvider.createIngressClassifierTunnelNshTrafficCaptureFlow(nodeId);
389
390         assertEquals(flow.getTableId().shortValue(), NwConstants.INTERNAL_TUNNEL_TABLE);
391         assertEquals(flow.getPriority().intValue(),
392                 OpenFlow13Provider.INGRESS_CLASSIFIER_CAPTURE_SFC_TUNNEL_TRAFFIC_PRIORITY);
393         assertEquals(flow.getId().getValue(),
394                 OpenFlow13Provider.INGRESS_CLASSIFIER_CAPTURE_SFC_TUNNEL_NSH_TRAFFIC_FLOW_NAME + nodeId.getValue());
395         assertEquals(flow.getCookie().getValue(),
396                 OpenFlow13Provider.INGRESS_CLASSIFIER_CAPTURE_SFC_TUNNEL_TRAFFIC_COOKIE);
397
398         checkMatchPacketType(flow.getMatch(), OpenFlow13Utils.PACKET_TYPE_NSH);
399         checkMatchTunId(flow.getMatch(), OpenFlow13Provider.SFC_TUNNEL_ID);
400
401         assertEquals(1, flow.getInstructions().getInstruction().size());
402         checkActionGotoTable(flow.getInstructions().getInstruction().get(0).getInstruction(),
403                 NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE);
404     }
405
406     //
407     // Internal util methods to check Flow Matches
408     //
409
410     private void checkMatchEmpty(Match match) {
411         assertNull(match.getPacketTypeMatch());
412         assertNull(match.getEthernetMatch());
413         assertNull(match.getIpMatch());
414         assertNull(match.getLayer3Match());
415         assertNull(match.getLayer4Match());
416         assertNull(match.augmentation(GeneralAugMatchNodesNodeTableFlow.class));
417     }
418
419     private void checkMatchPacketType(Match match, long packetType) {
420         assertEquals(packetType, match.getPacketTypeMatch().getPacketType().longValue());
421     }
422
423     private void checkMatchTunId(Match match, long value) {
424         GeneralAugMatchNodesNodeTableFlow genAug =
425                 match.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
426
427         assertNotNull(genAug);
428
429         List<ExtensionList> extensions = genAug.getExtensionList();
430         for (ExtensionList extensionList : extensions) {
431             Extension extension = extensionList.getExtension();
432             NxAugMatchNodesNodeTableFlow nxAugMatch = extension.augmentation(NxAugMatchNodesNodeTableFlow.class);
433
434             if (nxAugMatch.getNxmNxTunId() != null) {
435                 assertEquals(nxAugMatch.getNxmNxTunId().getValue().longValue(), value);
436             }
437         }
438     }
439
440     private void checkMatchTunDstIp(Match match, Ipv4Address value) {
441         GeneralAugMatchNodesNodeTableFlow genAug =
442                 match.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
443
444         assertNotNull(genAug);
445
446         List<ExtensionList> extensions = genAug.getExtensionList();
447         for (ExtensionList extensionList : extensions) {
448             Extension extension = extensionList.getExtension();
449             NxAugMatchNodesNodeTableFlow nxAugMatch = extension.augmentation(NxAugMatchNodesNodeTableFlow.class);
450
451             if (nxAugMatch.getNxmNxTunIpv4Dst() != null) {
452                 assertEquals(nxAugMatch.getNxmNxTunIpv4Dst().getIpv4Address(), value);
453             }
454         }
455     }
456
457     private void checkMatchEthNsh(Match match) {
458         assertEquals(match.getEthernetMatch().getEthernetType().getType().getValue().longValue(),
459                 OpenFlow13Utils.ETHERTYPE_NSH);
460     }
461
462     private void checkMatchInport(Match match, String inportStr) {
463         assertEquals(inportStr, match.getInPort().getValue());
464     }
465
466     private void checkMatchNsp(Match match, long nsp) {
467         GeneralAugMatchNodesNodeTableFlow genAug =
468                 match.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
469
470         assertNotNull(genAug);
471
472         List<ExtensionList> extensions = genAug.getExtensionList();
473         for (ExtensionList extensionList : extensions) {
474             Extension extension = extensionList.getExtension();
475             NxAugMatchNodesNodeTableFlow nxAugMatch = extension.augmentation(NxAugMatchNodesNodeTableFlow.class);
476
477             if (nxAugMatch.getNxmNxNsp() != null) {
478                 assertEquals(nxAugMatch.getNxmNxNsp().getValue().longValue(), nsp);
479             }
480         }
481     }
482
483     private void checkMatchNsi(Match match, short nsi) {
484         GeneralAugMatchNodesNodeTableFlow genAug =
485                 match.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
486
487         assertNotNull(genAug);
488
489         List<ExtensionList> extensions = genAug.getExtensionList();
490         for (ExtensionList extensionList : extensions) {
491             Extension extension = extensionList.getExtension();
492             NxAugMatchNodesNodeTableFlow nxAugMatch = extension.augmentation(NxAugMatchNodesNodeTableFlow.class);
493
494             if (nxAugMatch.getNxmNxNsi() != null) {
495                 assertEquals(nxAugMatch.getNxmNxNsi().getNsi().shortValue(), nsi);
496             }
497         }
498     }
499
500     private void checkMatchReg(Match match, Class<? extends NxmNxReg> reg, long value) {
501         GeneralAugMatchNodesNodeTableFlow genAug =
502                 match.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
503
504         assertNotNull(genAug);
505
506         List<ExtensionList> extensions = genAug.getExtensionList();
507         for (ExtensionList extensionList : extensions) {
508             Extension extension = extensionList.getExtension();
509             NxAugMatchNodesNodeTableFlow nxAugMatch = extension.augmentation(NxAugMatchNodesNodeTableFlow.class);
510
511             if (nxAugMatch.getNxmNxReg() != null) {
512                 assertEquals(nxAugMatch.getNxmNxReg().getReg(), reg);
513                 assertEquals(nxAugMatch.getNxmNxReg().getValue().longValue(), value);
514                 assertNull(nxAugMatch.getNxmNxReg().getMask());
515             }
516         }
517     }
518
519     //
520     // Internal util methods to check Flow Actions
521     //
522
523     private void checkActionResubmit(Instruction curInstruction, short nextTableId) {
524         assertTrue(curInstruction instanceof ApplyActionsCase);
525         boolean resubmitActionFound = false;
526         for (Action action : ((ApplyActionsCase) curInstruction).getApplyActions().getAction()) {
527             if (action.getAction() instanceof NxActionResubmitNodesNodeTableFlowWriteActionsCase) {
528                 NxActionResubmitNodesNodeTableFlowWriteActionsCase resubmitAction =
529                         (NxActionResubmitNodesNodeTableFlowWriteActionsCase) action.getAction();
530                 assertEquals(resubmitAction.getNxResubmit().getTable().shortValue(), nextTableId);
531                 resubmitActionFound = true;
532             }
533         }
534
535         assertTrue(resubmitActionFound);
536     }
537
538     private void checkActionGotoTable(Instruction curInstruction, short nextTableId) {
539         if (curInstruction instanceof GoToTableCase) {
540             GoToTableCase goToTablecase = (GoToTableCase) curInstruction;
541             assertEquals(goToTablecase.getGoToTable().getTableId().shortValue(), nextTableId);
542         } else {
543             fail();
544         }
545     }
546
547     private List<Action> checkApplyActionSize(Instruction curInstruction, int numActions) {
548         assertTrue(curInstruction instanceof ApplyActionsCase);
549         ApplyActionsCase action = (ApplyActionsCase) curInstruction;
550         assertEquals(numActions, action.getApplyActions().getAction().size());
551
552         return action.getApplyActions().getAction();
553     }
554
555     private void checkActionLoadTunIpv4(Action action, String ip) {
556         long ipl = InetAddresses.coerceToInteger(InetAddresses.forString(ip)) & 0xffffffffL;
557         NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad =
558                 (NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getAction();
559         DstNxTunIpv4DstCase tunDstTypeCase = (DstNxTunIpv4DstCase) regLoad.getNxRegLoad().getDst().getDstChoice();
560         assertEquals(Empty.getInstance(), tunDstTypeCase.getNxTunIpv4Dst());
561         assertEquals(regLoad.getNxRegLoad().getValue().longValue(), ipl);
562     }
563
564     private void checkActionLoadTunId(Action action, long tunId) {
565         NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad =
566                 (NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getAction();
567         DstNxTunIdCase mdTypeCase = (DstNxTunIdCase) regLoad.getNxRegLoad().getDst().getDstChoice();
568         assertEquals(Empty.getInstance(), mdTypeCase.getNxTunId());
569         assertEquals(regLoad.getNxRegLoad().getValue().longValue(), tunId);
570     }
571
572     private void checkActionOutport(Action action, String outport) {
573         OutputActionCase output = (OutputActionCase) action.getAction();
574         assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), outport);
575     }
576
577     private void checkActionMoveNsp(Action action, boolean checkSrc) {
578         NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
579                 (NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
580         if (checkSrc) {
581             assertEquals(Empty.getInstance(), ((SrcNxNspCase) regMove.getNxRegMove()
582                     .getSrc().getSrcChoice()).getNxNspDst());
583         } else {
584             assertEquals(Empty.getInstance(), ((DstNxNspCase) regMove.getNxRegMove()
585                     .getDst().getDstChoice()).getNxNspDst());
586         }
587     }
588
589     private void checkActionMoveNsi(Action action, boolean checkSrc) {
590         NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
591                 (NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
592         if (checkSrc) {
593             assertEquals(Empty.getInstance(), ((SrcNxNsiCase) regMove.getNxRegMove()
594                     .getSrc().getSrcChoice()).getNxNsiDst());
595         } else {
596             assertEquals(Empty.getInstance(), ((DstNxNsiCase) regMove.getNxRegMove()
597                     .getDst().getDstChoice()).getNxNsiDst());
598         }
599     }
600
601     private void checkActionMoveNsc1(Action action, boolean checkSrc) {
602         NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
603                 (NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
604         if (checkSrc) {
605             SrcNxNshc1Case src = (SrcNxNshc1Case) regMove.getNxRegMove().getSrc().getSrcChoice();
606             assertEquals(Empty.getInstance(), src.getNxNshc1Dst());
607         } else {
608             DstNxNshc1Case dst = (DstNxNshc1Case) regMove.getNxRegMove().getDst().getDstChoice();
609             assertEquals(Empty.getInstance(), dst.getNxNshc1Dst());
610         }
611     }
612
613     private void checkActionMoveNsc2(Action action, boolean checkSrc) {
614         NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
615                 (NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
616         if (checkSrc) {
617             SrcNxNshc2Case src = (SrcNxNshc2Case) regMove.getNxRegMove().getSrc().getSrcChoice();
618             assertEquals(Empty.getInstance(), src.getNxNshc2Dst());
619         } else {
620             DstNxNshc2Case dst = (DstNxNshc2Case) regMove.getNxRegMove().getDst().getDstChoice();
621             assertEquals(Empty.getInstance(), dst.getNxNshc2Dst());
622         }
623     }
624
625     private void checkActionMoveNsc4(Action action, boolean checkSrc) {
626         NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
627                 (NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
628         if (checkSrc) {
629             SrcNxNshc4Case src = (SrcNxNshc4Case) regMove.getNxRegMove().getSrc().getSrcChoice();
630             assertEquals(Empty.getInstance(), src.getNxNshc4Dst());
631         } else {
632             DstNxNshc4Case dst = (DstNxNshc4Case) regMove.getNxRegMove().getDst().getDstChoice();
633             assertEquals(Empty.getInstance(), dst.getNxNshc4Dst());
634         }
635     }
636
637     private void checkActionMoveTunId(Action action, boolean checkSrc) {
638         NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
639                 (NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
640         if (checkSrc) {
641             SrcNxTunIdCase src = (SrcNxTunIdCase) regMove.getNxRegMove().getSrc().getSrcChoice();
642             assertEquals(Empty.getInstance(), src.getNxTunId());
643         } else {
644             DstNxTunIdCase dst = (DstNxTunIdCase) regMove.getNxRegMove().getDst().getDstChoice();
645             assertEquals(Empty.getInstance(), dst.getNxTunId());
646         }
647     }
648
649     private void checkActionLoadReg(Action action, Class<? extends NxmNxReg> reg,
650                                     int startOffset,
651                                     int endOffset,
652                                     long value) {
653         NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad =
654                 (NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getAction();
655         assertEquals(reg, ((DstNxRegCase) regLoad.getNxRegLoad().getDst().getDstChoice()).getNxReg());
656         assertEquals(startOffset, regLoad.getNxRegLoad().getDst().getStart().intValue());
657         assertEquals(endOffset, regLoad.getNxRegLoad().getDst().getEnd().intValue());
658         assertEquals(value, regLoad.getNxRegLoad().getValue().longValue());
659     }
660
661     private void checkActionMoveReg(Action action, Class<? extends NxmNxReg> reg,
662                                     int startOffset,
663                                     int endOffset,
664                                     boolean checkSrc) {
665         NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
666                 (NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
667         if (checkSrc) {
668             assertEquals(reg, ((SrcNxRegCase) regMove.getNxRegMove().getSrc().getSrcChoice()).getNxReg());
669             assertEquals(startOffset, regMove.getNxRegMove().getSrc().getStart().intValue());
670             assertEquals(endOffset, regMove.getNxRegMove().getSrc().getEnd().intValue());
671         } else {
672             assertEquals(reg, ((DstNxRegCase) regMove.getNxRegMove().getDst().getDstChoice()).getNxReg());
673             assertEquals(startOffset, regMove.getNxRegMove().getDst().getStart().intValue());
674             assertEquals(endOffset, regMove.getNxRegMove().getDst().getEnd().intValue());
675         }
676     }
677
678     private void checkActionEncap(Action action, long packetType) {
679         NxActionEncapNodesNodeTableFlowApplyActionsCase encap =
680                 (NxActionEncapNodesNodeTableFlowApplyActionsCase) action.getAction();
681         assertEquals(packetType, encap.getNxEncap().getPacketType().longValue());
682     }
683
684     private void checkActionDecap(Action action) {
685         NxActionDecapNodesNodeTableFlowApplyActionsCase decap =
686                 (NxActionDecapNodesNodeTableFlowApplyActionsCase) action.getAction();
687         assertNotNull(decap.getNxDecap());
688     }
689
690 }