2 * Copyright (c) 2014 Contextream, Inc. and others. All rights reserved.
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
9 package org.opendaylight.lispflowmapping.southbound.lisp;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertTrue;
15 import java.net.DatagramPacket;
16 import java.nio.ByteBuffer;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.List;
21 import junitx.framework.ArrayAssert;
22 import junitx.framework.Assert;
24 import org.apache.commons.lang3.ArrayUtils;
25 import org.jmock.api.Invocation;
26 import org.junit.Before;
27 import org.junit.Ignore;
28 import org.junit.Test;
29 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
30 import org.opendaylight.lispflowmapping.lisp.type.AddressFamilyNumberEnum;
31 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
32 import org.opendaylight.lispflowmapping.lisp.type.LispMessageEnum;
33 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
34 import org.opendaylight.lispflowmapping.lisp.util.LispAFIConvertor;
35 import org.opendaylight.lispflowmapping.lisp.util.MapNotifyBuilderHelper;
36 import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
37 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
38 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
39 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.AddMapping;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.EidToLocatorRecord.Action;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.LispAFIAddress;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.MapRegister;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.MapRequest;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.RequestMapping;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.eidrecords.EidRecord;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.eidtolocatorrecords.EidToLocatorRecord;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.eidtolocatorrecords.EidToLocatorRecordBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.LispAddressContainer;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv4.Ipv4AddressBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv6.Ipv6AddressBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.locatorrecords.LocatorRecord;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.locatorrecords.LocatorRecordBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.mapnotifymessage.MapNotifyBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.mapreplymessage.MapReplyBuilder;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
58 import org.opendaylight.yangtools.yang.binding.Notification;
60 public class LispSouthboundServiceTest extends BaseTestCase {
62 private LispSouthboundService testedLispService;
63 private NotificationProviderService nps;
64 private byte[] mapRequestPacket;
65 private byte[] mapRegisterPacket;
66 private ValueSaverAction<Notification> lispNotificationSaver;
67 // private ValueSaverAction<MapRegister> mapRegisterSaver;
68 // private ValueSaverAction<MapRequest> mapRequestSaver;
69 private MapNotifyBuilder mapNotifyBuilder;
70 private MapReplyBuilder mapReplyBuilder;
71 private EidToLocatorRecordBuilder eidToLocatorBuilder;
73 private interface MapReplyIpv4SingleLocatorPos {
76 int LOCATOR_COUNT = 16;
77 int EID_MASK_LEN = 17;
81 int LOCATOR_RBIT = 33;
85 private interface MapReplyIpv4SecondLocatorPos {
86 int FIRST_LOCATOR_IPV4_LENGTH = 12;
87 int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
88 int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
89 int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
94 public void before() throws Exception {
96 // mapResolver = context.mock(IMapResolver.class);
97 // mapServer = context.mock(IMapServer.class);
98 testedLispService = new LispSouthboundService();
99 nps = context.mock(NotificationProviderService.class);
100 testedLispService.setNotificationProvider(nps);
101 lispNotificationSaver = new ValueSaverAction<Notification>();
102 // mapRegisterSaver = new ValueSaverAction<MapRegister>();
103 // mapRequestSaver = new ValueSaverAction<MapRequest>();
104 // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
105 // LISP(Type = 8 - Encapsulated)
106 // IP: 192.168.136.10 -> 1.2.3.4
108 // LISP(Type = 1 Map-Request
112 // Source EID not present
113 // Nonce: 0x3d8d2acd39c8d608
114 // ITR-RLOC AFI=1 Address=192.168.136.10
115 // Record 1: 1.2.3.4/32
116 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
117 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
118 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
119 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
120 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
121 + "0050 2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 c0 a8 88 0a 00 20 " //
122 + "0060 00 01 01 02 03 04"));
123 mapReplyBuilder = new MapReplyBuilder();
124 mapReplyBuilder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
125 mapReplyBuilder.setNonce((long) 0);
126 mapReplyBuilder.setEchoNonceEnabled(false);
127 mapReplyBuilder.setProbe(true);
128 mapReplyBuilder.setSecurityEnabled(true);
129 eidToLocatorBuilder = new EidToLocatorRecordBuilder();
130 String ip = "0.0.0.0";
131 eidToLocatorBuilder.setLispAddressContainer(getIPContainer(ip));
132 eidToLocatorBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
133 eidToLocatorBuilder.setRecordTtl(10);
134 eidToLocatorBuilder.setMapVersion((short) 0);
135 eidToLocatorBuilder.setMaskLength((short) 0);
136 eidToLocatorBuilder.setAction(Action.NativelyForward);
137 eidToLocatorBuilder.setAuthoritative(false);
138 // eidToLocatorBuilder.setPrefix(new LispIpv4Address(0));
139 // mapReply.addEidToLocator(eidToLocatorBuilder);
141 // IP: 192.168.136.10 -> 128.223.156.35
142 // UDP: 49289 -> 4342
143 // LISP(Type = 3 Map-Register, P=1, M=1
147 // AuthDataLength: 20 Data:
148 // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
149 // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
151 // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
152 // Priority/Weight: 1/100, Multicast Priority/Weight:
156 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
157 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
158 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
159 + "0030 00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
160 + "0040 71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
161 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
162 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
163 mapNotifyBuilder = new MapNotifyBuilder();
164 mapNotifyBuilder.setAuthenticationData(new byte[0]);
167 private LispAddressContainer getIPContainer(String ip) {
168 return LispAFIConvertor.toContainer(getIP(ip));
171 private org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv4.Ipv4Address getIP(String ip) {
172 return new Ipv4AddressBuilder().setIpv4Address(new Ipv4Address(ip)).setAfi((short) 1).build();
175 private org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv6.Ipv6Address getIPV6(String ip) {
176 return new Ipv6AddressBuilder().setIpv6Address(new Ipv6Address(ip)).setAfi((short) 2).build();
181 public void todos() throws Exception {
183 // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
184 // TODO: Non-Encapsulated packets
187 @Test(expected = LispMalformedPacketException.class)
188 public void mapRegister__IllegalPacket() throws Exception {
189 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
190 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 " //
191 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "));
193 handleMapRegisterPacket(mapRegisterPacket);
196 @Test(expected = LispMalformedPacketException.class)
197 public void mapRequest__IllegalPacket() throws Exception {
198 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
199 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
200 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
201 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 " //
202 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "));
203 handleMapRequestPacket(mapRequestPacket);
206 @Test(expected = LispMalformedPacketException.class)
207 public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
208 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
209 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 " //
210 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "));
211 handleMapRequestPacket(mapRequestPacket);
214 private MapRegister lastMapRegister() {
215 assertTrue(lispNotificationSaver.lastValue instanceof AddMapping);
216 AddMapping lastValue = (AddMapping) lispNotificationSaver.lastValue;
217 return lastValue.getMapRegister();
220 private MapRequest lastMapRequest() {
221 RequestMapping lastValue = (RequestMapping) lispNotificationSaver.lastValue;
222 return lastValue.getMapRequest();
226 public void mapRegister__TwoRlocs() throws Exception {
228 // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
229 // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
230 // Priority/Weight: 255/0
231 // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
232 // Multicast Priority/Weight: 255/0
233 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
234 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 " //
235 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 " //
236 + "0030 00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 " //
237 + "0040 e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 " //
238 + "0050 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 " //
239 + "0060 ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 " //
240 + "0070 00 01 c0 a8 88 33"));
242 oneOf(nps).publish(with(lispNotificationSaver));
244 handleMapRegisterPacket(mapRegisterPacket);
246 List<EidToLocatorRecord> eidRecords = lastMapRegister().getEidToLocatorRecord();
247 assertEquals(1, eidRecords.size());
248 EidToLocatorRecord eidRecord = eidRecords.get(0);
249 assertEquals(2, eidRecord.getLocatorRecord().size());
250 assertEquals(getIPContainer("10.1.0.110"), eidRecord.getLocatorRecord().get(0).getLispAddressContainer());
251 assertEquals(getIPContainer("192.168.136.51"), eidRecord.getLocatorRecord().get(1).getLispAddressContainer());
255 public void mapRegister__Ipv6Rloc() throws Exception {
256 // P bit (Proxy-Map-Reply): Set
257 // M bit (Want-Map-Notify): Set
262 // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
263 // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
265 // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
266 // Priority/Weight: 255/0
268 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
269 + "0010 00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 " //
270 + "0020 01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 " //
271 + "0030 00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 " //
272 + "0040 0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 " //
273 + "0050 00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff " //
274 + "0060 01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 " //
275 + "0070 00 01 0a 00 3a 9c"));
277 oneOf(nps).publish(with(lispNotificationSaver));
279 handleMapRegisterPacket(mapRegisterPacket);
281 EidToLocatorRecord eidToLocatorRecord = lastMapRegister().getEidToLocatorRecord().get(0);
282 assertEquals(getIPV6("2610:d0:ffff:192:0:0:0:1"), LispAFIConvertor.toAFI(eidToLocatorRecord.getLispAddressContainer()));
283 assertEquals(AddressFamilyNumberEnum.IP6,
284 AddressFamilyNumberEnum.valueOf(LispAFIConvertor.toAFI(eidToLocatorRecord.getLispAddressContainer()).getAfi()));
286 assertEquals(getIP("10.0.58.156"), LispAFIConvertor.toAFI(eidToLocatorRecord.getLocatorRecord().get(0).getLispAddressContainer()));
290 public void mapRegister__VerifyBasicFields() throws Exception {
291 oneOf(nps).publish(with(lispNotificationSaver));
292 handleMapRegisterPacket(mapRegisterPacket);
294 EidToLocatorRecord eidToLocator = lastMapRegister().getEidToLocatorRecord().get(0);
295 assertEquals(getIP("153.16.254.1"), LispAFIConvertor.toAFI(eidToLocator.getLispAddressContainer()));
297 assertEquals(1, eidToLocator.getLocatorRecord().size());
298 assertEquals(getIP("192.168.136.10"), LispAFIConvertor.toAFI(eidToLocator.getLocatorRecord().get(0).getLispAddressContainer()));
303 public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
304 oneOf(nps).publish(with(lispNotificationSaver));
305 mapNotifyBuilder = null;
307 assertNull(handleMapRegisterPacket(mapRegisterPacket));
311 public void mapRegister__NonSetMBit() throws Exception {
312 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
313 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df " //
314 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
315 + "0030 00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
316 + "0040 83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 " //
317 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
318 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
319 stubMapRegister(true);
321 handleMapRegisterPacket(registerWithNonSetMBit);
323 assertFalse(lastMapRegister().isWantMapNotify());
327 public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
328 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
329 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
330 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
331 + "0030 00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
332 + "0040 e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
333 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
334 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
335 stubMapRegister(true);
337 handleMapRegisterPacket(registerWithNonSetMBit);
338 assertFalse(lastMapRegister().isWantMapNotify());
342 public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
343 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
344 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
345 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
346 + "0030 00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
347 + "0040 4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
348 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
349 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
350 stubMapRegister(true);
352 handleMapRegisterPacket(registerWithNonSetMBit);
353 assertTrue(lastMapRegister().isWantMapNotify());
358 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
359 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
360 extraDataPacket[mapRegisterPacket.length] = 0x9;
361 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
362 stubMapRegister(true);
364 DatagramPacket dp = new DatagramPacket(extraDataPacket, extraDataPacket.length);
365 dp.setLength(mapRegisterPacket.length);
366 testedLispService.handlePacket(dp);
367 // Check map register fields.
369 // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
370 byte[] notifyResult = lastMapNotifyPacket().getData();
371 assertEquals(mapRegisterPacket.length, notifyResult.length);
375 private DatagramPacket lastMapReplyPacket() {
376 ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
377 return new DatagramPacket(serialize.array(), serialize.array().length);
380 private DatagramPacket lastMapNotifyPacket() {
381 if (mapNotifyBuilder.getEidToLocatorRecord() == null) {
382 mapNotifyBuilder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
384 mapNotifyBuilder.getEidToLocatorRecord().add(eidToLocatorBuilder.build());
385 mapNotifyBuilder.setNonce((long) 0);
386 mapNotifyBuilder.setKeyId((short) 0);
387 mapNotifyBuilder.setAuthenticationData(new byte[0]);
388 ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotifyBuilder.build());
389 return new DatagramPacket(serialize.array(), serialize.array().length);
394 public void mapNotify__VerifyBasicFields() throws Exception {
395 byte registerType = mapRegisterPacket[0];
396 assertEquals(LispMessageEnum.MapRegister.getValue(), registerType >> 4);
398 stubMapRegister(true);
400 byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
402 assertEquals(mapRegisterPacket.length, result.length);
404 byte expectedType = (byte) (LispMessageEnum.MapNotify.getValue() << 4);
405 assertHexEquals(expectedType, result[0]);
406 assertHexEquals((byte) 0x00, result[1]);
407 assertHexEquals((byte) 0x00, result[2]);
409 byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(mapRegisterPacket, 3, 16),
410 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
411 byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
412 Arrays.copyOfRange(result, 36, result.length));
413 ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData, notifyWithoutTypeWithOutAuthenticationData);
418 public void mapNotify__VerifyPort() throws Exception {
419 stubMapRegister(true);
421 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
422 assertEquals(LispMessage.PORT_NUM, notifyPacket.getPort());
426 public void mapRequest__VerifyBasicFields() throws Exception {
427 oneOf(nps).publish(with(lispNotificationSaver));
428 handleMapRequestAsByteArray(mapRequestPacket);
429 List<EidRecord> eids = lastMapRequest().getEidRecord();
430 assertEquals(1, eids.size());
431 LispAFIAddress lispAddress = LispAFIConvertor.toAFI(eids.get(0).getLispAddressContainer());
432 assertTrue(lispAddress instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv4.Ipv4Address);
433 assertEquals(getIP("1.2.3.4"), ((org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv4.Ipv4Address) lispAddress));
434 assertEquals((byte) 0x20, eids.get(0).getMask().byteValue());
435 assertEquals(0x3d8d2acd39c8d608L, lastMapRequest().getNonce().longValue());
436 // assertEquals(AddressFamilyNumberEnum.RESERVED,
437 // AddressFamilyNumberEnum.valueOf(LispAFIToContainerConvertorFactory.toAFI(
438 // lastMapRequest().getSourceEid().getLispAddressContainer()).getAfi()));
442 public void mapRequest__Ipv6Eid() throws Exception {
443 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
444 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
445 // (2610:d0:ffff:192::2)
448 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
449 // ITR-RLOC 1: 10.0.58.156
450 // Record 1: 2610:d0:ffff:192::2/128
451 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
452 // Authoritative, No-Action
454 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
455 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
456 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
457 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
458 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
459 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
460 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
461 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
462 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
463 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 " //
464 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 " //
465 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
467 oneOf(nps).publish(with(lispNotificationSaver));
470 handleMapRequestAsByteArray(mapRequestPacket);
471 assertEquals(getIPV6("2610:d0:ffff:192:0:0:0:1"), LispAFIConvertor.toAFI(lastMapRequest().getSourceEid().getLispAddressContainer()));
472 assertEquals(getIPV6("2610:d0:ffff:192:0:0:0:2"), LispAFIConvertor.toAFI(lastMapRequest().getEidRecord().get(0).getLispAddressContainer()));
477 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
478 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
479 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
480 // (2610:d0:ffff:192::2)
481 // encapsulated UDP source port: 4342
483 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
484 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
485 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
486 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
487 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
488 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
489 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
490 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
491 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
492 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 " //
493 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 " //
494 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
495 oneOf(nps).publish(with(lispNotificationSaver));
498 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
499 assertEquals(4342, replyPacket.getPort());
503 public void mapRequest__WithSourceEid() throws Exception {
504 // encapsulated LISP packet
505 // Source EID = 153.16.254.1
507 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 " //
508 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
509 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
510 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
511 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
512 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
513 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
514 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 " //
515 + "0080 00 01 0a 00 01 26"));
517 oneOf(nps).publish(with(lispNotificationSaver));
520 handleMapRequestAsByteArray(mapRequestPacket);
521 Assert.assertNotEquals(AddressFamilyNumberEnum.IP, LispAFIConvertor.toAFI(lastMapRequest().getSourceEid().getLispAddressContainer()));
527 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
528 eidToLocatorBuilder.setMaskLength((short) 0x20).setLispAddressContainer(LispAFIConvertor.toContainer(getIP("10.0.20.200")));
529 mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
533 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
535 assertEquals(28, result.length);
537 byte expectedLispMessageType = 2;
538 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
539 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
541 byte expectedRecordCount = (byte) 1;
542 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
544 assertEquals(eidToLocatorBuilder.getMaskLength().byteValue(), result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
545 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
546 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
551 public void mapReply__VerifyBasicIPv6() throws Exception {
552 eidToLocatorBuilder.setMaskLength((short) 0x80).setLispAddressContainer(LispAFIConvertor.toContainer(getIPV6("0:0:0:0:0:0:0:1")));
556 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
558 assertEquals(40, result.length);
560 byte expectedRecordCount = (byte) 1;
561 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
563 assertEquals(eidToLocatorBuilder.getMaskLength().byteValue(), result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
564 assertEquals(AddressFamilyNumberEnum.IP6.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
565 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
567 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
572 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
573 eidToLocatorBuilder.setLispAddressContainer(LispAFIConvertor.toContainer(getIPV6("0:0:0:0:0:0:0:1")));
574 eidToLocatorBuilder.getLocatorRecord().add(
575 new LocatorRecordBuilder().setLispAddressContainer(LispAFIConvertor.toContainer(getIPV6("0:0:0:0:0:0:0:2"))).build());
579 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
581 assertEquals(64, result.length);
583 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
584 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
586 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
587 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
592 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
595 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).getPort());
600 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
601 eidToLocatorBuilder.setMaskLength((short) 0x20).setLispAddressContainer(LispAFIConvertor.toContainer(getIP("10.0.20.200")));
602 eidToLocatorBuilder.getLocatorRecord().add(
603 new LocatorRecordBuilder().setRouted(false).setLispAddressContainer(LispAFIConvertor.toContainer(getIP("4.3.2.1"))).build());
606 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
607 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
612 public void mapReply__WithSingleLocator() throws Exception {
613 eidToLocatorBuilder.setMaskLength((short) 0x20)//
614 .setLispAddressContainer(LispAFIConvertor.toContainer(getIP("10.0.20.200")));
615 eidToLocatorBuilder.getLocatorRecord().add(
616 new LocatorRecordBuilder().setRouted(true).setLispAddressContainer(LispAFIConvertor.toContainer(getIP("4.3.2.1"))).build());
619 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
620 assertEquals(40, result.length);
622 byte expectedLocCount = 1;
623 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
625 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
627 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
628 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
633 public void mapReply__WithMultipleLocator() throws Exception {
634 eidToLocatorBuilder.getLocatorRecord().add(
635 new LocatorRecordBuilder().setRouted(true).setLispAddressContainer(LispAFIConvertor.toContainer(getIP("4.3.2.1"))).build());
636 eidToLocatorBuilder.getLocatorRecord().add(
637 new LocatorRecordBuilder().setRouted(true).setLispAddressContainer(LispAFIConvertor.toContainer(getIPV6("0:0:0:0:0:0:0:1"))).build());
640 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
641 assertEquals(64, result.length);
643 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
645 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
646 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
647 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
649 assertEquals(AddressFamilyNumberEnum.IP6.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
651 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
652 ArrayAssert.assertEquals(expectedIpv6Rloc,
653 Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR, MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
655 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
659 public void handleUnknownLispMessage() throws Exception {
660 // IP: 192.168.136.10 -> 128.223.156.35
661 // UDP: 49289 -> 4342
662 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
664 byte[] unknownTypePacket = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
665 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
666 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
667 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
668 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
669 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
670 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
671 assertNull(handlePacket(unknownTypePacket));
675 public void mapRequest__MultipleItrRlocs() throws Exception {
676 // this is what LISPmob sends when configured multiple RLOCs for single
678 // ITR-RLOC 1: 10.1.0.111
679 // ITR-RLOC 2: 192.168.136.51
681 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
682 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 " //
683 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 " //
684 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 " //
685 + "0040 08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 " //
686 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 " //
687 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 " //
688 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 " //
689 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 " //
690 + "0090 00 05 00 01 c0 a8 88 33"));
692 oneOf(nps).publish(with(lispNotificationSaver));
693 handleMapRequestAsByteArray(mapRequestPacket);
697 private void stubMapRegister(final boolean setNotifyFromRegister) {
698 allowing(nps).publish(with(lispNotificationSaver));
699 will(new SimpleAction() {
702 public Object invoke(Invocation invocation) throws Throwable {
703 if (setNotifyFromRegister) {
704 MapNotifyBuilderHelper.setFromMapRegister(mapNotifyBuilder, lastMapRegister());
711 private void stubHandleRequest() {
712 allowing(nps).publish(wany(Notification.class));
715 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
716 handleMapRequestPacket(inPacket);
717 return lastMapReplyPacket().getData();
720 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
721 handleMapRegisterPacket(inPacket);
722 return lastMapNotifyPacket().getData();
725 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
726 DatagramPacket dp = new DatagramPacket(inPacket, inPacket.length);
727 // Unless we explicitly set the source port, it will be -1, which breaks some tests
728 // This is till not the real port number, but it's better
729 dp.setPort(LispMessage.PORT_NUM);
730 testedLispService.handlePacket(dp);
731 return lastMapReplyPacket();
734 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
735 DatagramPacket dp = new DatagramPacket(inPacket, inPacket.length);
736 // Unless we explicitly set the source port, it will be -1, which breaks some tests
737 // This is till not the real port number, but it's better
738 dp.setPort(LispMessage.PORT_NUM);
739 testedLispService.handlePacket(dp);
740 if (mapNotifyBuilder == null) {
743 return lastMapNotifyPacket();
747 private DatagramPacket handlePacket(byte[] inPacket) {
748 // TODO get from mock
749 testedLispService.handlePacket(new DatagramPacket(inPacket, inPacket.length));
753 private byte[] extractWSUdpByteArray(String wiresharkHex) {
754 final int HEADER_LEN = 42;
755 byte[] res = new byte[1000];
756 String[] split = wiresharkHex.split(" ");
758 for (String cur : split) {
760 if (cur.length() == 2) {
762 if (counter > HEADER_LEN) {
763 res[counter - HEADER_LEN - 1] = (byte) Integer.parseInt(cur, 16);
768 return Arrays.copyOf(res, counter - HEADER_LEN);
771 @Test(expected = LispMalformedPacketException.class)
772 public void mapRequest__NoIPITRRLOC() throws Exception {
773 mapRequestPacket = hexToByteBuffer("10 00 " //
774 + "02 " // This means 3 ITR - RLOCs
775 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
776 + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 3)
777 + "40 05 00 00 00 00 00 00 " // MAC (ITR-RLOC #2 of 3)
778 + "40 05 11 22 34 56 78 90 " // MAC (ITR-RLOC #3 of 3)
779 + "00 20 00 01 01 02 03 04").array();
780 handleMapRequestPacket(mapRequestPacket);
785 // public void mapRequest__IPITRRLOCIsSecond() throws Exception {
786 // mapRequestPacket = hexToByteBuffer("10 00 " //
787 // + "01 " // This means 3 ITR - RLOCs
788 // + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
789 // + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 2)
790 // + "00 01 01 02 03 04 " // IP (ITR-RLOC #2 of 2)
791 // + "00 20 00 01 01 02 03 04").array();
792 // oneOf(nps).publish(with(lispNotificationSaver));
794 // DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
795 // assertEquals(2, lastMapRequest().getItrRlocs().size());
796 // assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(),
797 // packet.getAddress());
802 // public void mapRequest__MULTIPLEIPITRRLOCs() throws Exception {
803 // mapRequestPacket = hexToByteBuffer("10 00 " //
804 // + "01 " // This means 3 ITR - RLOCs
805 // + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
806 // + "00 01 01 02 03 04 " // IP (ITR-RLOC #1 of 2)
807 // + "00 01 c0 a8 88 0a " // MAC (ITR-RLOC #2 of 2)
808 // + "00 20 00 01 01 02 03 04").array();
809 // oneOf(nps).publish(with(lispNotificationSaver));
811 // DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
812 // assertEquals(2, lastMapRequest().getItrRloc().size());
813 // assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(),
814 // packet.getAddress());