BUG-2218: Keep existing link augmentations during discovery process
[controller.git] / opendaylight / protocol_plugins / openflow / src / test / java / org / opendaylight / controller / protocol_plugin / openflow / internal / FlowProgrammerServiceTest.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.protocol_plugin.openflow.internal;
11
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.List;
17
18 import org.junit.Assert;
19 import org.junit.Test;
20 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match;
21 import org.opendaylight.controller.sal.action.Action;
22 import org.opendaylight.controller.sal.action.Flood;
23 import org.opendaylight.controller.sal.action.FloodAll;
24 import org.opendaylight.controller.sal.action.HwPath;
25 import org.opendaylight.controller.sal.action.Loopback;
26 import org.opendaylight.controller.sal.action.Output;
27 import org.opendaylight.controller.sal.action.PopVlan;
28 import org.opendaylight.controller.sal.action.SetDlDst;
29 import org.opendaylight.controller.sal.action.SetDlSrc;
30 import org.opendaylight.controller.sal.action.SetNwDst;
31 import org.opendaylight.controller.sal.action.SetNwSrc;
32 import org.opendaylight.controller.sal.action.SetNwTos;
33 import org.opendaylight.controller.sal.action.SetTpDst;
34 import org.opendaylight.controller.sal.action.SetTpSrc;
35 import org.opendaylight.controller.sal.action.SetVlanId;
36 import org.opendaylight.controller.sal.action.SwPath;
37 import org.opendaylight.controller.sal.core.Node;
38 import org.opendaylight.controller.sal.core.NodeConnector;
39 import org.opendaylight.controller.sal.flowprogrammer.Flow;
40 import org.opendaylight.controller.sal.match.Match;
41 import org.opendaylight.controller.sal.match.MatchType;
42 import org.opendaylight.controller.sal.utils.EtherTypes;
43 import org.opendaylight.controller.sal.utils.IPProtocols;
44 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
45 import org.opendaylight.controller.sal.utils.NodeCreator;
46 import org.openflow.protocol.OFMatch;
47 import org.openflow.protocol.action.OFAction;
48 import org.openflow.util.U32;
49
50 public class FlowProgrammerServiceTest {
51
52     @Test
53     public void testSALtoOFFlowConverter() throws UnknownHostException {
54         Node node = NodeCreator.createOFNode(1000L);
55         NodeConnector port = NodeConnectorCreator.createNodeConnector(
56                 (short) 24, node);
57         NodeConnector oport = NodeConnectorCreator.createNodeConnector(
58                 (short) 30, node);
59         byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
60                 (byte) 0x9a, (byte) 0xbc };
61         byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
62                 (byte) 0x5e, (byte) 0x6f };
63         InetAddress srcIP = InetAddress.getByName("172.28.30.50");
64         InetAddress dstIP = InetAddress.getByName("171.71.9.52");
65         InetAddress ipMask = InetAddress.getByName("255.255.255.0");
66         short ethertype = EtherTypes.IPv4.shortValue();
67         short vlan = (short) 27;
68         byte vlanPr = 3;
69         Byte tos = 4;
70         byte proto = IPProtocols.TCP.byteValue();
71         short src = (short) 55000;
72         short dst = 80;
73
74         /*
75          * Create a SAL Flow aFlow
76          */
77         Match match = new Match();
78         match.setField(MatchType.IN_PORT, port);
79         match.setField(MatchType.DL_SRC, srcMac);
80         match.setField(MatchType.DL_DST, dstMac);
81         match.setField(MatchType.DL_TYPE, ethertype);
82         match.setField(MatchType.DL_VLAN, vlan);
83         match.setField(MatchType.DL_VLAN_PR, vlanPr);
84         match.setField(MatchType.NW_SRC, srcIP, ipMask);
85         match.setField(MatchType.NW_DST, dstIP, ipMask);
86         match.setField(MatchType.NW_TOS, tos);
87         match.setField(MatchType.NW_PROTO, proto);
88         match.setField(MatchType.TP_SRC, src);
89         match.setField(MatchType.TP_DST, dst);
90
91         Assert.assertTrue(match.isIPv4());
92
93         List<Action> actions = new ArrayList<Action>();
94         // Setting all the actions supported by of
95         actions.add(new PopVlan());
96         actions.add(new Output(oport));
97         actions.add(new Flood());
98         actions.add(new FloodAll());
99         actions.add(new SwPath());
100         actions.add(new HwPath());
101         actions.add(new Loopback());
102         byte mac[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 };
103         actions.add(new SetDlSrc(mac));
104         actions.add(new SetDlDst(mac));
105         actions.add(new SetNwSrc(dstIP));
106         actions.add(new SetNwDst(srcIP));
107         actions.add(new SetNwTos(3));
108         actions.add(new SetTpSrc(10));
109         actions.add(new SetTpDst(20));
110         actions.add(new SetVlanId(200));
111
112         Flow aFlow = new Flow(match, actions);
113
114         /*
115          * Convert the SAL aFlow to OF Flow
116          */
117         FlowConverter salToOF = new FlowConverter(aFlow);
118         OFMatch ofMatch = salToOF.getOFMatch();
119         List<OFAction> ofActions = salToOF.getOFActions();
120
121         /*
122          * Convert the OF Flow to SAL Flow bFlow
123          */
124         FlowConverter ofToSal = new FlowConverter(ofMatch, ofActions);
125         Flow bFlow = ofToSal.getFlow(node);
126         Match bMatch = bFlow.getMatch();
127         List<Action> bActions = bFlow.getActions();
128
129         /*
130          * Verify the converted SAL flow bFlow is equivalent to the original SAL Flow
131          */
132         Assert.assertTrue(((NodeConnector) match.getField(MatchType.IN_PORT)
133                 .getValue()).equals(((NodeConnector) bMatch.getField(
134                 MatchType.IN_PORT).getValue())));
135         Assert.assertTrue(Arrays.equals((byte[]) match.getField(
136                 MatchType.DL_SRC).getValue(), (byte[]) bMatch.getField(
137                 MatchType.DL_SRC).getValue()));
138         Assert.assertTrue(Arrays.equals((byte[]) match.getField(
139                 MatchType.DL_DST).getValue(), (byte[]) bMatch.getField(
140                 MatchType.DL_DST).getValue()));
141         Assert
142                 .assertTrue(((Short) match.getField(MatchType.DL_TYPE)
143                         .getValue()).equals((Short) bMatch.getField(
144                         MatchType.DL_TYPE).getValue()));
145         Assert
146                 .assertTrue(((Short) match.getField(MatchType.DL_VLAN)
147                         .getValue()).equals((Short) bMatch.getField(
148                         MatchType.DL_VLAN).getValue()));
149         Assert.assertTrue(((Byte) match.getField(MatchType.DL_VLAN_PR)
150                 .getValue()).equals((Byte) bMatch
151                 .getField(MatchType.DL_VLAN_PR).getValue()));
152         Assert.assertTrue(((InetAddress) match.getField(MatchType.NW_SRC)
153                 .getValue()).equals((InetAddress) bMatch.getField(
154                 MatchType.NW_SRC).getValue()));
155         Assert.assertTrue(((InetAddress) match.getField(MatchType.NW_SRC)
156                 .getMask()).equals((InetAddress) bMatch.getField(
157                 MatchType.NW_SRC).getMask()));
158         Assert.assertTrue(((InetAddress) match.getField(MatchType.NW_DST)
159                 .getValue()).equals((InetAddress) bMatch.getField(
160                 MatchType.NW_DST).getValue()));
161         Assert.assertTrue(((InetAddress) match.getField(MatchType.NW_DST)
162                 .getMask()).equals((InetAddress) bMatch.getField(
163                 MatchType.NW_DST).getMask()));
164         Assert
165                 .assertTrue(((Byte) match.getField(MatchType.NW_PROTO)
166                         .getValue()).equals((Byte) bMatch.getField(
167                         MatchType.NW_PROTO).getValue()));
168         Assert.assertTrue(((Byte) match.getField(MatchType.NW_TOS).getValue())
169                 .equals((Byte) bMatch.getField(MatchType.NW_TOS).getValue()));
170         Assert.assertTrue(((Short) match.getField(MatchType.TP_SRC).getValue())
171                 .equals((Short) bMatch.getField(MatchType.TP_SRC).getValue()));
172         Assert.assertTrue(((Short) match.getField(MatchType.TP_DST).getValue())
173                 .equals((Short) bMatch.getField(MatchType.TP_DST).getValue()));
174
175         // FlowConverter parses and sets the actions in the same order for sal match and of match
176         for (short i = 0; i < actions.size(); i++) {
177             Assert.assertTrue(actions.get(i).equals(bActions.get(i)));
178         }
179     }
180
181     @Test
182     public void testVlanNoneIdFlowConversion() throws Exception {
183         Node node = NodeCreator.createOFNode(1000L);
184
185         /*
186          * The value 0 is used to indicate that no VLAN ID is set
187          * for SAL Flow.
188          */
189         short vlan = (short) 0;
190
191         /*
192          * Create a SAL Flow aFlow
193          */
194         Match match = new Match();
195         match.setField(MatchType.DL_VLAN, vlan);
196
197         List<Action> actions = new ArrayList<Action>();
198
199         Flow aFlow = new Flow(match, actions);
200
201         /*
202          * Convert the SAL aFlow to OF Flow
203          */
204         FlowConverter salToOF = new FlowConverter(aFlow);
205         OFMatch ofMatch = salToOF.getOFMatch();
206         List<OFAction> ofActions = salToOF.getOFActions();
207
208         /*
209          * The value 0xffff (OFP_VLAN_NONE) is used to indicate
210          * that no VLAN ID is set for OF Flow.
211          */
212         Assert.assertEquals((short) 0xffff, ofMatch.getDataLayerVirtualLan());
213
214         /*
215          * Convert the OF Flow to SAL Flow bFlow
216          */
217         FlowConverter ofToSal = new FlowConverter(ofMatch, ofActions);
218         Flow bFlow = ofToSal.getFlow(node);
219         Match bMatch = bFlow.getMatch();
220
221         /*
222          * Verify the converted SAL flow bFlow is equivalent to the original SAL Flow
223          */
224         Assert
225                 .assertTrue(((Short) match.getField(MatchType.DL_VLAN)
226                         .getValue()).equals((Short) bMatch.getField(
227                         MatchType.DL_VLAN).getValue()));
228     }
229
230     @Test
231     public void testV6toSALFlowConversion() throws Exception {
232         Node node = NodeCreator.createOFNode(12L);
233         NodeConnector port = NodeConnectorCreator.createNodeConnector(
234                 (short) 34, node);
235         NodeConnector oport = NodeConnectorCreator.createNodeConnector(
236                 (short) 30, node);
237         byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
238                 (byte) 0x9a, (byte) 0xbc };
239         byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
240                 (byte) 0x5e, (byte) 0x6f };
241         InetAddress srcIP = InetAddress
242                 .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
243         InetAddress dstIP = InetAddress
244                 .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
245         InetAddress ipMask = InetAddress
246                 .getByName("ffff:ffff:ffff:ffff:0:0:0:0");
247         short ethertype = EtherTypes.IPv6.shortValue();
248         short vlan = (short) 27;
249         byte vlanPr = 3;
250         Byte tos = 4;
251         byte proto = IPProtocols.TCP.byteValue();
252         short src = (short) 55000;
253         short dst = 80;
254
255         /*
256          * Create a SAL Flow aFlow
257          */
258         Match aMatch = new Match();
259
260         aMatch.setField(MatchType.IN_PORT, port);
261         aMatch.setField(MatchType.DL_SRC, srcMac);
262         aMatch.setField(MatchType.DL_DST, dstMac);
263         aMatch.setField(MatchType.DL_TYPE, ethertype);
264         aMatch.setField(MatchType.DL_VLAN, vlan);
265         aMatch.setField(MatchType.DL_VLAN_PR, vlanPr);
266         aMatch.setField(MatchType.NW_SRC, srcIP, ipMask);
267         aMatch.setField(MatchType.NW_DST, dstIP, ipMask);
268         aMatch.setField(MatchType.NW_TOS, tos);
269         aMatch.setField(MatchType.NW_PROTO, proto);
270         aMatch.setField(MatchType.TP_SRC, src);
271         aMatch.setField(MatchType.TP_DST, dst);
272
273         Assert.assertTrue(aMatch.isIPv6());
274
275         List<Action> actions = new ArrayList<Action>();
276         // Setting all the actions supported by of for v6
277         actions.add(new PopVlan());
278         actions.add(new Output(oport));
279         actions.add(new Flood());
280         actions.add(new FloodAll());
281         actions.add(new SwPath());
282         actions.add(new HwPath());
283         actions.add(new Loopback());
284         byte mac[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 };
285         actions.add(new SetDlSrc(mac));
286         actions.add(new SetDlDst(mac));
287         //actions.add(new SetNwSrc(dstIP)); Nicira extensions do not provide IPv6 match addresses change
288         //actions.add(new SetNwDst(srcIP));
289         actions.add(new SetNwTos(3));
290         actions.add(new SetTpSrc(10));
291         actions.add(new SetTpDst(65535));
292         actions.add(new SetVlanId(200));
293
294         Flow aFlow = new Flow(aMatch, actions);
295
296         /*
297          * Convert the SAL aFlow to OF Flow
298          */
299         FlowConverter salToOF = new FlowConverter(aFlow);
300         V6Match v6Match = (V6Match) salToOF.getOFMatch();
301         // need this hardcoding here to make the test pass.
302         // this should not be a problem in actual code.
303         // in the test the sal match is converted to a V6 match.
304         // we lose the wildcard info as the V6 match is used for nicira extensions
305         // and nicira deals with wildcards in a different way.
306         // converting the V6 match back to sal match is not going to preserve the wildcard info.
307         // and we need the wildcard info for reading the vlan pcp now.
308         // when creating a V6Match using the readFrom method
309         // we do convert the nicira extensions format correctly to populate the wildcard info.
310         v6Match.setWildcards(U32.t(Long.valueOf(~OFMatch.OFPFW_DL_VLAN_PCP)));
311         List<OFAction> ofActions = salToOF.getOFActions();
312
313         /*
314          * Convert the OF Flow to SAL Flow bFlow
315          */
316         FlowConverter ofToSal = new FlowConverter(v6Match, ofActions);
317         Flow bFlow = ofToSal.getFlow(node);
318         Match bMatch = bFlow.getMatch();
319         List<Action> bActions = bFlow.getActions();
320
321         /*
322          * Verify the converted SAL flow bFlow is equivalent to the original SAL Flow
323          */
324         Assert.assertTrue(((NodeConnector) aMatch.getField(MatchType.IN_PORT)
325                 .getValue()).equals(((NodeConnector) bMatch.getField(
326                 MatchType.IN_PORT).getValue())));
327         Assert.assertTrue(Arrays.equals((byte[]) aMatch.getField(
328                 MatchType.DL_SRC).getValue(), (byte[]) bMatch.getField(
329                 MatchType.DL_SRC).getValue()));
330         Assert.assertTrue(Arrays.equals((byte[]) aMatch.getField(
331                 MatchType.DL_DST).getValue(), (byte[]) bMatch.getField(
332                 MatchType.DL_DST).getValue()));
333         Assert.assertTrue(((Short) aMatch.getField(MatchType.DL_TYPE)
334                 .getValue()).equals((Short) bMatch.getField(MatchType.DL_TYPE)
335                 .getValue()));
336         Assert.assertTrue(((Short) aMatch.getField(MatchType.DL_VLAN)
337                 .getValue()).equals((Short) bMatch.getField(MatchType.DL_VLAN)
338                 .getValue()));
339         Assert.assertTrue(((Byte) aMatch.getField(MatchType.DL_VLAN_PR)
340                 .getValue()).equals((Byte) bMatch
341                 .getField(MatchType.DL_VLAN_PR).getValue()));
342         Assert.assertTrue(((InetAddress) aMatch.getField(MatchType.NW_SRC)
343                 .getValue()).equals((InetAddress) bMatch.getField(
344                 MatchType.NW_SRC).getValue()));
345         Assert.assertTrue(((InetAddress) aMatch.getField(MatchType.NW_SRC)
346                 .getMask()).equals((InetAddress) bMatch.getField(
347                 MatchType.NW_SRC).getMask()));
348         Assert.assertTrue(((InetAddress) aMatch.getField(MatchType.NW_DST)
349                 .getValue()).equals((InetAddress) bMatch.getField(
350                 MatchType.NW_DST).getValue()));
351         Assert.assertTrue(((InetAddress) aMatch.getField(MatchType.NW_DST)
352                 .getMask()).equals((InetAddress) bMatch.getField(
353                 MatchType.NW_DST).getMask()));
354         Assert.assertTrue(((Byte) aMatch.getField(MatchType.NW_PROTO)
355                 .getValue()).equals((Byte) bMatch.getField(MatchType.NW_PROTO)
356                 .getValue()));
357         Assert.assertTrue(((Byte) aMatch.getField(MatchType.NW_TOS).getValue())
358                 .equals((Byte) bMatch.getField(MatchType.NW_TOS).getValue()));
359         Assert
360                 .assertTrue(((Short) aMatch.getField(MatchType.TP_SRC)
361                         .getValue()).equals((Short) bMatch.getField(
362                         MatchType.TP_SRC).getValue()));
363         Assert
364                 .assertTrue(((Short) aMatch.getField(MatchType.TP_DST)
365                         .getValue()).equals((Short) bMatch.getField(
366                         MatchType.TP_DST).getValue()));
367
368         // FlowConverter parses and sets the actions in the same order for sal match and of match
369         for (short i = 0; i < actions.size(); i++) {
370             Assert.assertTrue(actions.get(i).equals(bActions.get(i)));
371         }
372     }
373
374     @Test
375     public void testV6MatchToSALMatchToV6MatchConversion()
376             throws UnknownHostException {
377         NodeConnector port = NodeConnectorCreator.createNodeConnector(
378                 (short) 24, NodeCreator.createOFNode(6L));
379         byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
380                 (byte) 0x9a, (byte) 0xbc };
381         byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
382                 (byte) 0x5e, (byte) 0x6f };
383         InetAddress srcIP = InetAddress
384                 .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
385         InetAddress dstIP = InetAddress
386                 .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
387         InetAddress ipMask = null;//InetAddress.getByName("ffff:ffff:ffff:ffff:0:0:0:0");
388         short ethertype = EtherTypes.IPv6.shortValue();
389         short vlan = (short) 27;
390         byte vlanPr = 3;
391         Byte tos = 4;
392         byte proto = IPProtocols.TCP.byteValue();
393         short src = (short) 55000;
394         short dst = 80;
395
396         /*
397          * Create a SAL Flow aFlow
398          */
399         Match aMatch = new Match();
400
401         aMatch.setField(MatchType.IN_PORT, port);
402         aMatch.setField(MatchType.DL_SRC, srcMac);
403         aMatch.setField(MatchType.DL_DST, dstMac);
404         aMatch.setField(MatchType.DL_TYPE, ethertype);
405         aMatch.setField(MatchType.DL_VLAN, vlan);
406         aMatch.setField(MatchType.DL_VLAN_PR, vlanPr);
407         aMatch.setField(MatchType.NW_SRC, srcIP, ipMask);
408         aMatch.setField(MatchType.NW_DST, dstIP, ipMask);
409         aMatch.setField(MatchType.NW_TOS, tos);
410         aMatch.setField(MatchType.NW_PROTO, proto);
411         aMatch.setField(MatchType.TP_SRC, src);
412         aMatch.setField(MatchType.TP_DST, dst);
413
414         Assert.assertTrue(aMatch.isIPv6());
415
416     }
417 }