added length check for mask
[openflowjava.git] / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / util / MatchSerializerTest.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. 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.openflowjava.protocol.impl.util;
10
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.UnpooledByteBufAllocator;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.junit.Assert;
18 import org.junit.Test;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntry;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntryBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntry;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntryBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntry;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntryBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv4Src;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Dst;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Flabel;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTarget;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Src;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm0Class;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm1Class;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 /**
47  * @author michal.polkorab
48  *
49  */
50 public class MatchSerializerTest {
51     
52     private static final Logger LOG = LoggerFactory
53             .getLogger(MatchSerializerTest.class);
54
55     /**
56      * Test for correct serialization of Ipv4Address match entry
57      */
58     @Test
59     public void testIpv4Src() {
60         MatchBuilder builder = new MatchBuilder();
61         builder.setType(OxmMatchType.class);
62         List<MatchEntries> entries = new ArrayList<>();
63         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();
64         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
65         entriesBuilder.setOxmMatchField(Ipv4Src.class);
66         entriesBuilder.setHasMask(false);
67         Ipv4AddressMatchEntryBuilder addressBuilder = new Ipv4AddressMatchEntryBuilder();
68         addressBuilder.setIpv4Address(new Ipv4Address("1.2.3.4"));
69         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, addressBuilder.build());
70         entries.add(entriesBuilder.build());
71         builder.setMatchEntries(entries);
72         Match match = builder.build();
73         
74         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
75         MatchSerializer.encodeMatch(match, out);
76         
77         Assert.assertEquals("Wrong type", 1, out.readUnsignedShort());
78         out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
79         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
80         Assert.assertEquals("Wrong field and mask", 22, out.readUnsignedByte());
81         out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES);
82         Assert.assertEquals("Wrong ip address (first number)", 1, out.readUnsignedByte());
83         Assert.assertEquals("Wrong ip address (second number)", 2, out.readUnsignedByte());
84         Assert.assertEquals("Wrong ip address (third number)", 3, out.readUnsignedByte());
85         Assert.assertEquals("Wrong ip address (fourth number)", 4, out.readUnsignedByte());
86     }
87     
88     /**
89      * Test for correct serialization of Ipv6Address match entry
90      */
91     @Test
92     public void testIpv6Various() {
93         MatchBuilder builder = new MatchBuilder();
94         builder.setType(OxmMatchType.class);
95         List<MatchEntries> entries = new ArrayList<>();
96         // ipv6 match entry with correct Ipv6 address
97         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();
98         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
99         entriesBuilder.setOxmMatchField(Ipv6Src.class);
100         entriesBuilder.setHasMask(false);
101         Ipv6AddressMatchEntryBuilder addressBuilder = new Ipv6AddressMatchEntryBuilder();
102         addressBuilder.setIpv6Address(new Ipv6Address("1:2:3:4:5:6:7:8"));
103         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
104         entries.add(entriesBuilder.build());
105         // ipv6 match entry with abbreviated Ipv6 address
106         entriesBuilder = new MatchEntriesBuilder();
107         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
108         entriesBuilder.setOxmMatchField(Ipv6NdTarget.class);
109         entriesBuilder.setHasMask(false);
110         addressBuilder = new Ipv6AddressMatchEntryBuilder();
111         addressBuilder.setIpv6Address(new Ipv6Address("1:2::6:7:8"));
112         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
113         entries.add(entriesBuilder.build());
114         // ipv6 match entry with abbreviated Ipv6 address
115         entriesBuilder = new MatchEntriesBuilder();
116         entriesBuilder.setOxmClass(Nxm1Class.class);
117         entriesBuilder.setOxmMatchField(Ipv6Dst.class);
118         entriesBuilder.setHasMask(false);
119         addressBuilder = new Ipv6AddressMatchEntryBuilder();
120         addressBuilder.setIpv6Address(new Ipv6Address("1::8"));
121         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
122         entries.add(entriesBuilder.build());
123         // ipv6 match entry with abbreviated Ipv6 address
124         entriesBuilder = new MatchEntriesBuilder();
125         entriesBuilder.setOxmClass(Nxm1Class.class);
126         entriesBuilder.setOxmMatchField(Ipv6Dst.class);
127         entriesBuilder.setHasMask(false);
128         addressBuilder = new Ipv6AddressMatchEntryBuilder();
129         addressBuilder.setIpv6Address(new Ipv6Address("::1"));
130         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
131         entries.add(entriesBuilder.build());
132         // ipv6 match entry with abbreviated Ipv6 address
133         entriesBuilder = new MatchEntriesBuilder();
134         entriesBuilder.setOxmClass(Nxm0Class.class);
135         entriesBuilder.setOxmMatchField(Ipv6Dst.class);
136         entriesBuilder.setHasMask(false);
137         addressBuilder = new Ipv6AddressMatchEntryBuilder();
138         addressBuilder.setIpv6Address(new Ipv6Address("::"));
139         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
140         entries.add(entriesBuilder.build());
141         // ipv6 match entry with incorrect Ipv6 address (longer)
142         entriesBuilder = new MatchEntriesBuilder();
143         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
144         entriesBuilder.setOxmMatchField(Ipv6Dst.class);
145         entriesBuilder.setHasMask(false);
146         addressBuilder = new Ipv6AddressMatchEntryBuilder();
147         addressBuilder.setIpv6Address(new Ipv6Address("1:2:3:4:5:6:7:8:9"));
148         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
149         entries.add(entriesBuilder.build());
150         builder.setMatchEntries(entries);
151         Match match = builder.build();
152         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
153         MatchSerializer.encodeMatch(match, out);
154         
155         Assert.assertEquals("Wrong type", 1, out.readUnsignedShort());
156         out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
157         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
158         Assert.assertEquals("Wrong field and mask", 52, out.readUnsignedByte());
159         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
160         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
161         Assert.assertEquals("Wrong ipv6 address", 2, out.readUnsignedShort());
162         Assert.assertEquals("Wrong ipv6 address", 3, out.readUnsignedShort());
163         Assert.assertEquals("Wrong ipv6 address", 4, out.readUnsignedShort());
164         Assert.assertEquals("Wrong ipv6 address", 5, out.readUnsignedShort());
165         Assert.assertEquals("Wrong ipv6 address", 6, out.readUnsignedShort());
166         Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort());
167         Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort());
168         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
169         Assert.assertEquals("Wrong field and mask", 62, out.readUnsignedByte());
170         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
171         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
172         Assert.assertEquals("Wrong ipv6 address", 2, out.readUnsignedShort());
173         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
174         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
175         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
176         Assert.assertEquals("Wrong ipv6 address", 6, out.readUnsignedShort());
177         Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort());
178         Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort());
179         Assert.assertEquals("Wrong class", 0x0001, out.readUnsignedShort());
180         Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte());
181         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
182         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
183         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
184         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
185         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
186         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
187         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
188         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
189         Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort());
190         Assert.assertEquals("Wrong class", 0x0001, out.readUnsignedShort());
191         Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte());
192         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
193         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
194         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
195         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
196         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
197         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
198         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
199         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
200         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
201         Assert.assertEquals("Wrong class", 0x0000, out.readUnsignedShort());
202         Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte());
203         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
204         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
205         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
206         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
207         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
208         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
209         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
210         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
211         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
212         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
213         Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte());
214         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
215         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
216         Assert.assertEquals("Wrong ipv6 address", 2, out.readUnsignedShort());
217         Assert.assertEquals("Wrong ipv6 address", 3, out.readUnsignedShort());
218         Assert.assertEquals("Wrong ipv6 address", 4, out.readUnsignedShort());
219         Assert.assertEquals("Wrong ipv6 address", 5, out.readUnsignedShort());
220         Assert.assertEquals("Wrong ipv6 address", 6, out.readUnsignedShort());
221         Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort());
222         Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort());
223     }
224     
225     /**
226      * Test for correct serialization of Ipv4Address match entry
227      */
228     @Test
229     public void testIpv6Flabel() {
230         Match match = buildIpv6FLabelMatch(0x0f9e8dL, false, null);
231         
232         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
233         MatchSerializer.encodeMatch(match, out);
234         
235         Assert.assertEquals("Wrong type", 1, out.readUnsignedShort());
236         out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
237         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
238         Assert.assertEquals("Wrong field and mask", 28<<1, out.readUnsignedByte());
239         out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES);
240         byte[] label = new byte[4];
241         out.readBytes(label);
242         
243         LOG.debug("label: "+ByteBufUtils.bytesToHexString(label));
244         Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d}, label);
245     }
246     
247     /**
248      * Test for correct serialization of Ipv4Address match entry with mask
249      */
250     @Test
251     public void testIpv6FlabelWithMask() {
252         Match match = buildIpv6FLabelMatch(0x0f9e8dL, true, new byte[]{0, 0x0c, 0x7b, 0x6a});
253         
254         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
255         MatchSerializer.encodeMatch(match, out);
256         
257         Assert.assertEquals("Wrong type", 1, out.readUnsignedShort());
258         out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
259         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
260         Assert.assertEquals("Wrong field and mask", 28<<1 | 1, out.readUnsignedByte());
261         out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES);
262         byte[] labelAndMask = new byte[8];
263         out.readBytes(labelAndMask);
264         
265         LOG.debug("label: "+ByteBufUtils.bytesToHexString(labelAndMask));
266         Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d, 0, 0x0c, 0x7b, 0x6a}, labelAndMask);
267     }
268     
269     /**
270      * Test for correct serialization of Ipv4Address match entry with wrong mask
271      */
272     @Test
273     public void testIpv6FlabelWithMaskBad() {
274         Match match = buildIpv6FLabelMatch(0x0f9e8dL, true, new byte[]{0x0c, 0x7b, 0x6a});
275         
276         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
277         
278         try {
279             MatchSerializer.encodeMatch(match, out);
280             Assert.fail("incorrect length of mask ignored");
281         } catch (IllegalArgumentException e) {
282             //expected
283         }
284     }
285
286     /**
287      * @param labelValue ipv6 flow label
288      * @param hasMask
289      * @param mask ipv6 flow label mask
290      * @return
291      */
292     private static Match buildIpv6FLabelMatch(long labelValue, boolean hasMask, byte[] mask) {
293         MatchBuilder builder = new MatchBuilder();
294         builder.setType(OxmMatchType.class);
295         List<MatchEntries> entries = new ArrayList<>();
296         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();
297         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
298         entriesBuilder.setOxmMatchField(Ipv6Flabel.class);
299         entriesBuilder.setHasMask(hasMask);
300         Ipv6FlabelMatchEntryBuilder ip6FLabelBuilder = new Ipv6FlabelMatchEntryBuilder();
301         ip6FLabelBuilder.setIpv6Flabel(new Ipv6FlowLabel(labelValue));
302         entriesBuilder.addAugmentation(Ipv6FlabelMatchEntry.class, ip6FLabelBuilder.build());
303         MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();
304         maskBuilder.setMask(mask);
305         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());
306         entries.add(entriesBuilder.build());
307         builder.setMatchEntries(entries);
308         Match match = builder.build();
309         return match;
310     }
311     
312     
313
314 }