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