Merge "Drop Felix Gogo"
[openflowplugin.git] / openflowplugin / src / test / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / match / MatchResponseConvertorTest.java
1 /*
2  * Copyright (c) 2014 NEC Corporation 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.openflowplugin.openflow.md.core.sal.convertor.match;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotEquals;
13
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.Optional;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.opendaylight.openflowplugin.api.OFConstants;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
24 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthDst;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthSrc;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthDstCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthSrcCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthTypeCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPortCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanVidCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.dst._case.EthDstBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.src._case.EthSrcBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.type._case.EthTypeBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.port._case.InPortBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.vid._case.VlanVidBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
59
60 /**
61  * Unit test for {@link MatchConvertorImpl}.
62  */
63 public class MatchResponseConvertorTest {
64     private static final BigInteger DPID = BigInteger.TEN;
65     private static final Long IN_PORT = 6L;
66     private static final String URI_IN_PORT =
67             "openflow:" + DPID + ":" + IN_PORT;
68     private static final MacAddress MAC_SRC =
69             MacAddress.getDefaultInstance("00:11:22:33:44:55");
70     private static final MacAddress MAC_DST =
71             MacAddress.getDefaultInstance("fa:fb:fc:fd:fe:ff");
72     private static final int ETHTYPE_IPV4 = 0x800;
73     private static final short VLAN_PCP = 7;
74     private static final Ipv4Address IPV4_SRC =
75             Ipv4Address.getDefaultInstance("192.168.10.254");
76     private static final Ipv4Address IPV4_DST =
77             Ipv4Address.getDefaultInstance("10.1.2.3");
78
79     private static final int DL_VLAN_NONE = 0xffff;
80     private ConvertorManager convertorManager;
81
82     @Before
83     public void setUp() {
84         OpenflowPortsUtil.init();
85         convertorManager = ConvertorManagerFactory.createDefaultManager();
86     }
87
88     /**
89      * Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchResponseConvertor#convert(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchEntriesGrouping, org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData)} }.
90      */
91     @Test
92     public void testFromOFMatchToSALMatch() {
93         List<MatchEntry> entries = createDefaultMatchEntry();
94
95         int[] vids = {
96                 // Match packet with VLAN tag regardless of its value.
97                 -1,
98
99                 // Match untagged frame.
100                 0,
101
102                 // Match packet with VLAN tag and VID equals the specified value.
103                 1, 20, 4095,
104         };
105
106         for (int vid : vids) {
107             List<MatchEntry> MatchEntry =
108                     new ArrayList<MatchEntry>(entries);
109             MatchEntry.add(toOfVlanVid(vid));
110             org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match ofMatch =
111                     createOFMatch(MatchEntry);
112
113             final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(OFConstants.OFP_VERSION_1_3);
114             data.setDatapathId(DPID);
115             final MatchBuilder builder = convert(ofMatch, data);
116             checkDefault(builder);
117             VlanMatch vlanMatch = builder.getVlanMatch();
118             int expectedVid = (vid < 0) ? 0 : vid;
119             Boolean expectedCfi = vid != 0;
120             assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
121                     getValue().intValue());
122             assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
123             assertEquals(null, vlanMatch.getVlanPcp());
124         }
125     }
126
127     /**
128      * Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchV10ResponseConvertor#convert(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10, org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData)} }.
129      */
130     @Test
131     public void testFromOFMatchV10ToSALMatch() {
132         int[] vids = {
133                 // Match untagged frame.
134                 DL_VLAN_NONE,
135
136                 // Match packet with VLAN tag and VID equals the specified value.
137                 1, 20, 4095,
138         };
139         short[] dscps = {
140                 0, 1, 20, 40, 62, 63,
141         };
142
143         FlowWildcardsV10Builder wcBuilder = new FlowWildcardsV10Builder();
144         for (int vid : vids) {
145             for (short dscp : dscps) {
146                 short tos = (short) (dscp << 2);
147                 MatchV10Builder builder = new MatchV10Builder();
148                 builder.setDlSrc(MAC_SRC).setDlDst(MAC_DST).setDlVlan(vid).
149                         setDlVlanPcp(VLAN_PCP).setDlType(ETHTYPE_IPV4).
150                         setInPort(IN_PORT.intValue()).
151                         setNwSrc(IPV4_SRC).setNwDst(IPV4_DST).setNwTos(tos);
152                 wcBuilder.setAll(false).setNwProto(true).setTpSrc(true).
153                         setTpDst(true);
154                 if (vid == DL_VLAN_NONE) {
155                     wcBuilder.setDlVlanPcp(true);
156                 }
157
158                 FlowWildcardsV10 wc = wcBuilder.build();
159                 MatchV10 ofMatch = builder.setWildcards(wc).build();
160                 final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(OFConstants.OFP_VERSION_1_0);
161                 data.setDatapathId(DPID);
162                 Match match = convert(ofMatch, data).build();
163                 checkDefaultV10(match, wc, vid);
164
165                 IpMatch ipMatch = match.getIpMatch();
166                 assertEquals(null, ipMatch.getIpProtocol());
167                 assertEquals(dscp, ipMatch.getIpDscp().getValue().shortValue());
168                 assertEquals(null, ipMatch.getIpEcn());
169
170                 // Set all wildcard bits.
171                 wc = wcBuilder.setAll(true).build();
172                 ofMatch = builder.setWildcards(wc).build();
173                 match = convert(ofMatch, data).build();
174                 checkDefaultV10(match, wc, vid);
175                 assertEquals(null, match.getIpMatch());
176             }
177         }
178     }
179
180     private static void checkDefault(final MatchBuilder builder) {
181         EthernetMatch ethMatch = builder.getEthernetMatch();
182         assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
183         assertEquals(null, ethMatch.getEthernetSource().getMask());
184         assertEquals(MAC_DST, ethMatch.getEthernetDestination().getAddress());
185         assertEquals(null, ethMatch.getEthernetDestination().getMask());
186         assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
187                 getValue().intValue());
188
189         NodeConnectorId inPort = builder.getInPort();
190         assertEquals(URI_IN_PORT, inPort.getValue());
191     }
192
193     private static org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match createOFMatch(final List<MatchEntry> entries) {
194         org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder builder =
195                 new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder();
196         return builder.setType(OxmMatchType.class).setMatchEntry(entries).
197                 build();
198     }
199
200     private static List<MatchEntry> createDefaultMatchEntry() {
201         List<MatchEntry> entries = new ArrayList<>();
202         entries.add(toOfPort(InPort.class, IN_PORT));
203
204         MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
205         EthSrcCaseBuilder ethSrcCaseBuilder = new EthSrcCaseBuilder();
206
207         EthSrcBuilder ethSrcBuilder = new EthSrcBuilder();
208         ethSrcBuilder.setMacAddress(MAC_SRC);
209         ethSrcCaseBuilder.setEthSrc(ethSrcBuilder.build());
210         matchEntryBuilder.setMatchEntryValue(ethSrcCaseBuilder.build());
211         matchEntryBuilder.setOxmMatchField(EthSrc.class);
212         entries.add(matchEntryBuilder.build());
213
214
215         EthDstCaseBuilder ethDstCaseBuilder = new EthDstCaseBuilder();
216         EthDstBuilder ethDstBuilder = new EthDstBuilder();
217         ethDstBuilder.setMacAddress(MAC_DST);
218         ethDstCaseBuilder.setEthDst(ethDstBuilder.build());
219         matchEntryBuilder.setMatchEntryValue(ethDstCaseBuilder.build());
220         matchEntryBuilder.setOxmMatchField(EthDst.class);
221         entries.add(matchEntryBuilder.build());
222
223         entries.add(toOfEthernetType(ETHTYPE_IPV4));
224         return entries;
225     }
226
227     private static MatchEntry toOfEthernetType(final int ethType) {
228         MatchEntryBuilder builder = new MatchEntryBuilder();
229         builder.setOxmClass(OpenflowBasicClass.class);
230         builder.setHasMask(false);
231         builder.setOxmMatchField(EthType.class);
232         EthTypeCaseBuilder ethTypeCaseBuilder = new EthTypeCaseBuilder();
233         EthTypeBuilder ethTypeBuilder = new EthTypeBuilder();
234         EtherType etherType = new EtherType(ethType);
235         ethTypeBuilder.setEthType(etherType);
236         ethTypeCaseBuilder.setEthType(ethTypeBuilder.build());
237         builder.setMatchEntryValue(ethTypeCaseBuilder.build());
238         return builder.build();
239     }
240
241     private static MatchEntry toOfPort(final Class<? extends MatchField> field,
242                                 final Long portNumber) {
243         MatchEntryBuilder builder = new MatchEntryBuilder();
244         builder.setOxmClass(OpenflowBasicClass.class);
245         builder.setHasMask(false);
246         builder.setOxmMatchField(field);
247         InPortCaseBuilder inPortCaseBuilder = new InPortCaseBuilder();
248         InPortBuilder portBuilder = new InPortBuilder();
249         portBuilder.setPortNumber(new PortNumber(portNumber));
250         inPortCaseBuilder.setInPort(portBuilder.build());
251         builder.setMatchEntryValue(inPortCaseBuilder.build());
252         return builder.build();
253     }
254
255     private static MatchEntry toOfVlanVid(final int vid) {
256         MatchEntryBuilder builder = new MatchEntryBuilder();
257         boolean cfi = true;
258         Integer vidValue = vid;
259         byte[] mask = null;
260         builder.setOxmClass(OpenflowBasicClass.class);
261         builder.setOxmMatchField(VlanVid.class);
262         VlanVidCaseBuilder vlanVidCaseBuilder = new VlanVidCaseBuilder();
263         if (vid == 0) {
264             // Match untagged frame.
265             cfi = false;
266         } else if (vid < 0) {
267             // Match packet with VLAN tag regardless of its value.
268             mask = new byte[]{0x10, 0x00};
269             vidValue = 0;
270         }
271
272         VlanVidBuilder vlanVidBuilder = new VlanVidBuilder();
273         vlanVidBuilder.setCfiBit(cfi);
274         vlanVidBuilder.setVlanVid(vidValue);
275         boolean hasMask = mask != null;
276         if (hasMask) {
277             vlanVidBuilder.setMask(mask);
278         }
279         vlanVidCaseBuilder.setVlanVid(vlanVidBuilder.build());
280         builder.setHasMask(hasMask);
281         builder.setMatchEntryValue(vlanVidCaseBuilder.build());
282         return builder.build();
283     }
284
285     private static void checkDefaultV10(final Match match, final FlowWildcardsV10 wc, final int vid) {
286         EthernetMatch ethMatch = match.getEthernetMatch();
287         if (wc.isDLSRC()) {
288             if (ethMatch != null) {
289                 assertEquals(null, ethMatch.getEthernetSource());
290             }
291         } else {
292             assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
293         }
294
295         if (ethMatch != null) {
296             if (wc.isDLDST()) {
297                 assertEquals(null, ethMatch.getEthernetDestination());
298             } else {
299                 assertNotEquals(null, ethMatch.getEthernetDestination());
300                 assertEquals(MAC_DST,
301                         ethMatch.getEthernetDestination().getAddress());
302             }
303         }
304
305         if (wc.isDLTYPE()) {
306             if (ethMatch != null) {
307                 assertEquals(null, ethMatch.getEthernetType());
308             }
309             assertEquals(null, match.getLayer3Match());
310         } else {
311             assert ethMatch != null;
312             assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
313                     getValue().intValue());
314
315             Ipv4Match ipv4Match = (Ipv4Match) match.getLayer3Match();
316             assertEquals(IPV4_SRC.getValue() + "/32",
317                     ipv4Match.getIpv4Source().getValue());
318             assertEquals(IPV4_DST.getValue() + "/32",
319                     ipv4Match.getIpv4Destination().getValue());
320         }
321
322         VlanMatch vlanMatch = match.getVlanMatch();
323         if (wc.isDLVLAN()) {
324             assertEquals(null, vlanMatch);
325         } else {
326             int expectedVid;
327             Boolean expectedCfi;
328             if (vid == DL_VLAN_NONE) {
329                 expectedVid = 0;
330                 expectedCfi = Boolean.FALSE;
331             } else {
332                 expectedVid = vid;
333                 expectedCfi = Boolean.TRUE;
334             }
335             assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
336                     getValue().intValue());
337             assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
338
339             if (wc.isDLVLANPCP()) {
340                 assertEquals(null, vlanMatch.getVlanPcp());
341             } else {
342                 assertEquals(VLAN_PCP,
343                         vlanMatch.getVlanPcp().getValue().shortValue());
344             }
345         }
346     }
347
348     private MatchBuilder convert(MatchV10 match, VersionDatapathIdConvertorData data) {
349         final Optional<MatchBuilder> salMatchOptional = convertorManager.convert(match, data);
350
351         return salMatchOptional.orElse(new MatchBuilder());
352     }
353
354     private MatchBuilder convert(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match match, VersionDatapathIdConvertorData data) {
355         final Optional<MatchBuilder> salMatchOptional = convertorManager.convert(match, data);
356
357         return salMatchOptional.orElse(new MatchBuilder());
358     }
359 }