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