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