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 io.netty.buffer.Unpooled.wrappedBuffer;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertTrue;
15 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA1;
16 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA2;
17 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA3;
18 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.KEY_ID;
19 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.NONCE;
20 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.SITE_ID;
21 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.XTR_ID;
22 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.joinArrays;
24 import io.netty.channel.socket.DatagramPacket;
25 import java.net.InetSocketAddress;
26 import java.net.UnknownHostException;
27 import java.nio.ByteBuffer;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.List;
31 import junitx.framework.ArrayAssert;
32 import org.apache.commons.lang3.ArrayUtils;
33 import org.junit.Before;
34 import org.junit.BeforeClass;
35 import org.junit.Ignore;
36 import org.junit.Test;
37 import org.mockito.AdditionalMatchers;
38 import org.mockito.ArgumentCaptor;
39 import org.mockito.ArgumentMatchers;
40 import org.mockito.InOrder;
41 import org.mockito.Mockito;
42 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
43 import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
44 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
45 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
46 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
47 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
48 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
49 import org.opendaylight.lispflowmapping.mapcache.AuthKeyDb;
50 import org.opendaylight.lispflowmapping.southbound.ConcurrentLispSouthboundStats;
51 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
52 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterCache;
53 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
54 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.afn.safi.rev130704.AddressFamily;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4BinaryAfi;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4PrefixBinaryAfi;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv6PrefixBinaryAfi;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKeyBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValue;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValueBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkeyBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord.Action;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapreplymessage.MapReplyBuilder;
80 import org.opendaylight.yangtools.yang.binding.Notification;
82 public class LispSouthboundHandlerTest extends BaseTestCase {
84 private LispSouthboundHandler testedLispService;
85 private byte[] mapRequestPacket;
86 private byte[] mapRegisterPacket;
87 private MapNotifyBuilder mapNotifyBuilder;
88 private MapReplyBuilder mapReplyBuilder;
89 private MappingRecordBuilder mappingRecordBuilder;
90 private MapRegisterCache mapRegisterCache;
91 private LispSouthboundPlugin mockLispSouthboundPlugin;
92 private LispSouthboundPlugin contextMockLispSouthboundPlugin;
93 private static final long CACHE_RECORD_TIMEOUT = 90000;
95 private static AuthKeyDb akdb;
96 private static AuthenticationKeyDataListener akdl;
98 private interface MapReplyIpv4SingleLocatorPos {
101 int LOCATOR_COUNT = 16;
102 int EID_MASK_LEN = 17;
106 int LOCATOR_RBIT = 33;
110 private interface MapReplyIpv4SecondLocatorPos {
111 int FIRST_LOCATOR_IPV4_LENGTH = 12;
112 int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
113 int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
114 int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
117 @SuppressWarnings("unchecked")
119 public static void initTests() {
120 akdb = Mockito.mock(AuthKeyDb.class);
121 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
123 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
124 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
125 "2610:d0:ffff:192:0:0:0:1/128"))))
126 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
127 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
128 "153.16.254.1/32"))))
129 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
130 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
131 "125.124.123.122/8", new InstanceIdType(21L)))))
132 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
133 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asMacEid(
134 "0a:0b:0c:0d:0e:0f"))))
135 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
136 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
137 "f0f:f0f:f0f:f0f:f0f:f0f:f0f:f0f/8"))))
138 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
139 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
141 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
143 akdl = Mockito.mock(AuthenticationKeyDataListener.class);
144 Mockito.when(akdl.authKeysForEidsUnchanged(Mockito.anyList(), Mockito.anyLong())).thenReturn(true);
149 public void before() throws Exception {
151 mockLispSouthboundPlugin = Mockito.mock(LispSouthboundPlugin.class);
152 contextMockLispSouthboundPlugin = context.mock(LispSouthboundPlugin.class);
153 Mockito.when(mockLispSouthboundPlugin.isMapRegisterCacheEnabled()).thenReturn(true);
154 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCacheTimeout()).thenReturn(CACHE_RECORD_TIMEOUT);
155 mapRegisterCache = new MapRegisterCache();
156 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
157 Mockito.when(mockLispSouthboundPlugin.getDataBroker()).thenReturn(Mockito.mock(DataBroker.class));
158 Mockito.when(mockLispSouthboundPlugin.getAkdb()).thenReturn(akdb);
159 Mockito.when(mockLispSouthboundPlugin.getAuthenticationKeyDataListener()).thenReturn(akdl);
160 ConcurrentLispSouthboundStats lispSouthboundStats = new ConcurrentLispSouthboundStats();
161 Mockito.when(mockLispSouthboundPlugin.getStats()).thenReturn(lispSouthboundStats);
162 testedLispService = new LispSouthboundHandler(mockLispSouthboundPlugin);
164 // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
165 // LISP(Type = 8 - Encapsulated)
166 // IP: 192.168.136.10 -> 1.2.3.4
168 // LISP(Type = 1 Map-Request
172 // Source EID not present
173 // Nonce: 0x3d8d2acd39c8d608
174 // ITR-RLOC AFI=1 Address=192.168.136.10
175 // Record 1: 1.2.3.4/32
176 mapRequestPacket = extractWSUdpByteArray(
177 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
178 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
179 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
180 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
181 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
182 + "0050 2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 c0 a8 88 0a 00 20 "
183 + "0060 00 01 01 02 03 04");
184 mapReplyBuilder = new MapReplyBuilder();
185 mapReplyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
186 mapReplyBuilder.setNonce((long) 0);
187 mapReplyBuilder.setEchoNonceEnabled(false);
188 mapReplyBuilder.setProbe(true);
189 mapReplyBuilder.setSecurityEnabled(true);
190 mappingRecordBuilder = new MappingRecordBuilder();
191 String ip = "0.0.0.0";
192 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid(ip + "/0"));
193 mappingRecordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
194 mappingRecordBuilder.setRecordTtl(10);
195 mappingRecordBuilder.setMapVersion((short) 0);
196 mappingRecordBuilder.setAction(Action.NativelyForward);
197 mappingRecordBuilder.setAuthoritative(false);
198 // eidToLocatorBuilder.setPrefix(new LispIpv4Address(0));
199 // mapReply.addEidToLocator(eidToLocatorBuilder);
201 // IP: 192.168.136.10 -> 128.223.156.35
202 // UDP: 49289 -> 4342
203 // LISP(Type = 3 Map-Register, P=1, M=1
207 // AuthDataLength: 20 Data:
208 // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
209 // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
211 // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
212 // Priority/Weight: 1/100, Multicast Priority/Weight:
216 mapRegisterPacket = extractWSUdpByteArray(
217 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
218 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
219 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
220 + "0030 00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
221 + "0040 71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
222 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
223 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
224 mapNotifyBuilder = new MapNotifyBuilder();
225 mapNotifyBuilder.setAuthenticationData(new byte[0]);
230 public void todos() throws Exception {
232 // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
233 // TODO: Non-Encapsulated packets
236 @Test(expected = LispMalformedPacketException.class)
237 public void mapRegister__IllegalPacket() throws Exception {
238 mapRegisterPacket = extractWSUdpByteArray(
239 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
240 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
241 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 ");
243 handleMapRegisterPacket(mapRegisterPacket);
246 @Test(expected = LispMalformedPacketException.class)
247 public void mapRequest__IllegalPacket() throws Exception {
248 mapRequestPacket = extractWSUdpByteArray(
249 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
250 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
251 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
252 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
253 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d ");
254 handleMapRequestPacket(mapRequestPacket);
257 @Test(expected = LispMalformedPacketException.class)
258 public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
259 mapRequestPacket = extractWSUdpByteArray(
260 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
261 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
262 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 ");
263 handleMapRequestPacket(mapRequestPacket);
267 public void mapRegister__TwoRlocs() throws Exception {
269 // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
270 // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
271 // Priority/Weight: 255/0
272 // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
273 // Multicast Priority/Weight: 255/0
274 mapRegisterPacket = extractWSUdpByteArray(
275 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
276 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
277 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "
278 + "0030 00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 "
279 + "0040 e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 "
280 + "0050 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 "
281 + "0060 ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 "
282 + "0070 00 01 c0 a8 88 33");
284 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
285 handleMapRegisterPacket(mapRegisterPacket);
286 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
288 List<MappingRecordItem> eidRecords = captor.getValue().getMapRegister().getMappingRecordItem();
289 assertEquals(1, eidRecords.size());
290 MappingRecord eidRecord = eidRecords.get(0).getMappingRecord();
291 assertEquals(2, eidRecord.getLocatorRecord().size());
292 assertEquals(LispAddressUtil.asIpv4Rloc("10.1.0.110"), eidRecord.getLocatorRecord().get(0).getRloc());
293 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.51"), eidRecord.getLocatorRecord().get(1).getRloc());
297 public void mapRegister__Ipv6Rloc() throws Exception {
298 // P bit (Proxy-Map-Reply): Set
299 // M bit (Want-Map-Notify): Set
304 // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
305 // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
307 // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
308 // Priority/Weight: 255/0
310 mapRegisterPacket = extractWSUdpByteArray(
311 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
312 + "0010 00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 "
313 + "0020 01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 "
314 + "0030 00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 "
315 + "0040 0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 "
316 + "0050 00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff "
317 + "0060 01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 "
318 + "0070 00 01 0a 00 3a 9c");
320 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
321 handleMapRegisterPacket(mapRegisterPacket);
322 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
323 MappingRecord eidToLocatorRecord =
324 captor.getValue().getMapRegister().getMappingRecordItem().get(0).getMappingRecord();
326 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:1/128"),
327 eidToLocatorRecord.getEid());
328 assertEquals(Ipv6PrefixBinaryAfi.class, eidToLocatorRecord.getEid().getAddressType());
330 assertEquals(LispAddressUtil.asIpv4Rloc("10.0.58.156"), eidToLocatorRecord.getLocatorRecord().get(0).getRloc());
334 public void mapRegister__VerifyBasicFields() throws Exception {
335 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
336 handleMapRegisterPacket(mapRegisterPacket);
337 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
338 MappingRecord eidToLocator =
339 captor.getValue().getMapRegister().getMappingRecordItem().get(0).getMappingRecord();
341 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"), eidToLocator.getEid());
342 assertEquals(1, eidToLocator.getLocatorRecord().size());
343 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.10"), eidToLocator.getLocatorRecord().get(0).getRloc());
347 public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
348 mapNotifyBuilder = null;
349 assertNull(handleMapRegisterPacket(mapRegisterPacket));
353 public void mapRegister__NonSetMBit() throws Exception {
354 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
355 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
356 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
357 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
358 + "0030 00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
359 + "0040 83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 "
360 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
361 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
363 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
364 handleMapRegisterPacket(registerWithNonSetMBit);
365 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
366 assertFalse(captor.getValue().getMapRegister().isWantMapNotify());
370 public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
371 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
372 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
373 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
374 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
375 + "0030 00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
376 + "0040 e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
377 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
378 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
380 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
381 handleMapRegisterPacket(registerWithNonSetMBit);
382 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
383 assertFalse(captor.getValue().getMapRegister().isWantMapNotify());
387 public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
388 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
389 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
390 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
391 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
392 + "0030 00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
393 + "0040 4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
394 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
395 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
397 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
398 handleMapRegisterPacket(registerWithNonSetMBit);
399 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
400 assertTrue(captor.getValue().getMapRegister().isWantMapNotify());
404 * Tests whether handling of map-register message will generate mapping-keep-alive notification.
407 public void mapRegister_isMappingKeepAliveAndMapNotifyGenerated() throws InterruptedException,
408 UnknownHostException {
409 byte[] eidPrefixAfi = new byte[] {
414 byte[] eidPrefix = new byte[] {
416 0x0a, 0x0a, 0x0a, 0x0a
419 //send stream of byte -> map register message
420 InOrder inOrder = Mockito.inOrder(mockLispSouthboundPlugin);
421 final MapRegisterCacheKey cacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
422 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(cacheKey, mapRegisterCache);
423 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
424 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
425 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
426 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
427 cacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
429 //sending the same byte stream -> map register second time
430 captor = ArgumentCaptor.forClass(AddMapping.class);
431 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
432 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
434 //mapping-keep-alive message should be generated
435 MapRegisterCacheTestUtil.afterSecondMapRegisterInvocationValidation(
436 mockLispSouthboundPlugin, eidPrefixAfi, eidPrefix);
439 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix) {
440 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
443 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) {
444 final byte[] mapRegisterMessage = MapRegisterCacheTestUtil.joinArrays(DATA1, NONCE, KEY_ID,
445 authenticationData, DATA2, eidPrefixAfi, eidPrefix, DATA3, XTR_ID, SITE_ID);
446 handlePacket(mapRegisterMessage);
450 * It tests whether map register message is stored to local cache with Ipv4 EidPrefix.
453 public void mapRegister_cacheWithEidPrefixIpv4Test() throws InterruptedException {
454 byte[] eidPrefixAfi = new byte[] {
459 byte[] eidPrefix = new byte[] {
461 0x0a, 0x0a, 0x0a, 0x0a
464 cacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
468 * It tests whether map register message is stored to local cache with Ipv6 EidPrefix.
471 public void mapRegister_cacheWithEidPrefixIpv6Test() throws InterruptedException {
472 byte[] eidPrefixAfi = new byte[] {
477 byte[] eidPrefix = new byte[] {
479 0x0f, 0x0f, 0x0f, 0x0f,
481 0x0f, 0x0f, 0x0f, 0x0f,
483 0x0f, 0x0f, 0x0f, 0x0f,
485 0x0f, 0x0f, 0x0f, 0x0f
488 byte[] authenticationData = new byte[] {
490 0x41,(byte)0x83,0x13,0x7C,
491 0x48,(byte)0xEE,0x75,(byte)0x9A,
492 0x4,(byte)0x8C,0x46,(byte)0xA6,
493 0x1B,0x13,(byte)0xC8,0x4D,
494 (byte)0xA1,0x17,0x53,(byte)0xC3
497 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
501 * It tests whether map register message is stored to local cache with Mac 48bits EidPrefix.
504 public void mapRegister_cacheWithEidPrefixMac48Test() throws InterruptedException {
505 byte[] eidPrefixAfi = new byte[] {
510 byte[] eidPrefix = new byte[] {
512 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
515 byte[] authenticationData = new byte[] {
517 (byte)0xB2,(byte)0x8E,0x6,(byte)0x9D,
518 0x61,(byte)0xD8,0xC,0x24,
519 (byte)0x80,0x61,0x5A,0x20,
520 0xD,0x50,0x5E,(byte)0xAE,
521 0x47,(byte)0xF7,(byte)0x86,0x36
523 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
527 * It tests whether map register message is stored to local cache with Lcaf EidPrefix (inside Ipv4).
530 public void mapRegister_cacheWithEidPrefixLcafTest() throws InterruptedException {
531 byte[] eidPrefixAfi = new byte[] {
536 //following lcaf prefixed variables are defined according to https://tools.ietf
537 // .org/html/draft-ietf-lisp-lcaf-12#section-4.1
538 byte[] lcafRsvd1 = new byte[]{0x00};
539 byte[] lcafFlags = new byte[]{0x00};
540 byte[] lcafType = new byte[]{0x02};
541 byte[] lcafIIDMaskLength = new byte[]{0x20};
542 byte[] lcafLength = new byte[] {0x00, 0x0a};
543 byte[] lcafInstanceId = new byte[]{0x00, 0x00, 0x00, 0x15};
544 byte[] lcafAfi = new byte[] {0x00, 0x01};
545 byte[] lcafAddress = new byte[] {0x7d, 0x7c, 0x7b, 0x7a};
547 byte[] eidPrefix = joinArrays(lcafRsvd1, lcafFlags, lcafType, lcafIIDMaskLength, lcafLength, lcafInstanceId,
548 lcafAfi, lcafAddress);
550 byte[] authenticationData = new byte[] {
551 //authentication data length
554 0x68, 0x1d, (byte) 0x9e, 0x6e,
556 0x5e, 0x32, (byte) 0x88, 0x1a,
558 (byte) 0xae, 0x6b, (byte) 0xe3, 0x40,
560 0x30, (byte) 0x0b, (byte) 0xb6, (byte) 0xa0,
562 0x71, (byte) 0xf4, (byte) 0x8c, 0x5f
566 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
570 * It tests whether map register message is stored to local cache.
572 public void cacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) throws
573 InterruptedException {
574 final MapRegisterCacheKey mapRegisterCacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
576 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(mapRegisterCacheKey, mapRegisterCache);
577 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
578 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, authenticationData);
579 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
580 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
581 mapRegisterCacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
586 Checks whether old record from cache will expire and is replaced with new record.
588 add to empty cache record with timestamp older then 90 second - one object
589 add the same entry through calling of handleMapRegister
590 check that removeEntry() and addEntry() (or refreshEntry() was called on mocked object for mapRegisterCache
593 public void mapRegister_cacheRecordExpirationTest() throws InterruptedException {
594 //tests handling of map register message when next message comes:
596 //after cache entry timeout
597 cacheRecordExpirationTest(true);
599 //before cache entry timout
600 cacheRecordExpirationTest(false);
603 private void cacheRecordExpirationTest(boolean cacheRecordTimeouted) throws InterruptedException {
604 mapRegisterCache = Mockito.mock(MapRegisterCache.class);
605 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
607 final byte[] eidPrefixAfi = new byte[] {0x00, 0x01};
608 final byte[] eidPrefix = new byte[] {0x0a, 0x0a, 0x0a, 0x0a};
610 MapRegisterCacheKeyBuilder cacheKeyBld = new MapRegisterCacheKeyBuilder();
611 cacheKeyBld.setXtrId(XTR_ID);
612 cacheKeyBld.setEidPrefix(eidPrefix);
613 cacheKeyBld.setSiteId(SITE_ID);
615 MapRegisterCacheMetadataBuilder cacheMetadataBld = new MapRegisterCacheMetadataBuilder();
616 cacheMetadataBld.setTimestamp(System.currentTimeMillis() - (cacheRecordTimeouted ? CACHE_RECORD_TIMEOUT : 0L));
617 cacheMetadataBld.setWantMapNotify(false);
618 cacheMetadataBld.setEidLispAddress(new ArrayList<>());
620 MapRegisterCacheValueBuilder cacheValueBld = new MapRegisterCacheValueBuilder();
621 cacheValueBld.setMapRegisterCacheMetadata(cacheMetadataBld.build());
622 cacheValueBld.setPacketData(MapRegisterCacheTestUtil.joinArrays(DATA1, KEY_ID, DATA2, eidPrefixAfi,
623 eidPrefix, DATA3, XTR_ID, SITE_ID));
626 final MapRegisterCacheKey cacheKey = cacheKeyBld.build();
627 final MapRegisterCacheValue cacheValue = cacheValueBld.build();
629 Mockito.when(mapRegisterCache.getEntry(Mockito.eq(cacheKey))).thenReturn(cacheRecordTimeouted ? null :
631 Mockito.when(mapRegisterCache.refreshEntry(Mockito.eq(cacheKey))).thenReturn(cacheValue);
633 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
634 Mockito.verify(mockLispSouthboundPlugin, Mockito.atLeastOnce()).sendNotificationIfPossible(
635 Mockito.any(AddMapping.class));
637 InOrder inOrder = Mockito.inOrder(mapRegisterCache);
638 inOrder.verify(mapRegisterCache).getEntry(Mockito.eq(cacheKey));
640 if (cacheRecordTimeouted) {
641 inOrder.verify(mapRegisterCache).addEntry(Mockito.eq(cacheKey), AdditionalMatchers.not(Mockito.eq(
644 inOrder.verify(mapRegisterCache).refreshEntry(Mockito.eq(cacheKey));
650 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
651 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
652 extraDataPacket[mapRegisterPacket.length] = 0x9;
653 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
655 DatagramPacket dp = new DatagramPacket(wrappedBuffer(extraDataPacket), new InetSocketAddress(0),
656 new InetSocketAddress(0));
657 testedLispService.handlePacket(dp);
658 // Check map register fields.
660 // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
661 byte[] notifyResult = lastMapNotifyPacket().content().array();
662 assertEquals(mapRegisterPacket.length, notifyResult.length);
666 private DatagramPacket lastMapReplyPacket() {
667 ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
668 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
671 private DatagramPacket lastMapNotifyPacket() {
672 if (mapNotifyBuilder.getMappingRecordItem() == null) {
673 mapNotifyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
675 mapNotifyBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
676 mappingRecordBuilder.build()).build());
677 mapNotifyBuilder.setNonce((long) 0);
678 mapNotifyBuilder.setKeyId((short) 0);
679 mapNotifyBuilder.setAuthenticationData(new byte[0]);
680 ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotifyBuilder.build());
681 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
686 public void mapNotify__VerifyBasicFields() throws Exception {
687 byte registerType = mapRegisterPacket[0];
688 assertEquals(MessageType.MapRegister.getIntValue(), registerType >> 4);
690 byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
692 assertEquals(mapRegisterPacket.length, result.length);
694 byte expectedType = (byte) (MessageType.MapNotify.getIntValue() << 4);
695 assertHexEquals(expectedType, result[0]);
696 assertHexEquals((byte) 0x00, result[1]);
697 assertHexEquals((byte) 0x00, result[2]);
699 byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(
700 Arrays.copyOfRange(mapRegisterPacket, 3, 16),
701 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
702 byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
703 Arrays.copyOfRange(result, 36, result.length));
704 ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData,
705 notifyWithoutTypeWithOutAuthenticationData);
710 public void mapNotify__VerifyPort() throws Exception {
711 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
712 assertEquals(LispMessage.PORT_NUM, notifyPacket.recipient().getPort());
716 public void mapRequest__VerifyBasicFields() throws Exception {
717 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
718 handleMapRequestAsByteArray(mapRequestPacket);
719 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
720 List<EidItem> eids = captor.getValue().getMapRequest().getEidItem();
721 assertEquals(1, eids.size());
722 Eid lispAddress = eids.get(0).getEid();
723 assertEquals(Ipv4PrefixBinaryAfi.class, lispAddress.getAddressType());
724 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32"), lispAddress);
725 assertEquals(0x3d8d2acd39c8d608L, captor.getValue().getMapRequest().getNonce().longValue());
729 public void mapRequest__Ipv6Eid() throws Exception {
730 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
731 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
732 // (2610:d0:ffff:192::2)
735 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
736 // ITR-RLOC 1: 10.0.58.156
737 // Record 1: 2610:d0:ffff:192::2/128
738 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
739 // Authoritative, No-Action
741 mapRequestPacket = extractWSUdpByteArray(
742 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
743 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
744 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
745 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
746 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
747 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
748 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
749 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
750 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
751 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
752 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
753 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
755 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
756 handleMapRequestAsByteArray(mapRequestPacket);
757 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
758 assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"),
759 captor.getValue().getMapRequest().getSourceEid().getEid());
760 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:2/128"),
761 captor.getValue().getMapRequest().getEidItem().get(0).getEid());
766 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
767 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
768 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
769 // (2610:d0:ffff:192::2)
770 // encapsulated UDP source port: 4342
772 mapRequestPacket = extractWSUdpByteArray(
773 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
774 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
775 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
776 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
777 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
778 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
779 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
780 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
781 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
782 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
783 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
784 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
786 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
787 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
788 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any());
789 assertEquals(4342, replyPacket.recipient().getPort());
793 public void mapRequest__WithSourceEid() throws Exception {
794 // encapsulated LISP packet
795 // Source EID = 153.16.254.1
797 mapRequestPacket = extractWSUdpByteArray(
798 "0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 "
799 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
800 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
801 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
802 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
803 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
804 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
805 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 "
806 + "0080 00 01 0a 00 01 26");
808 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
809 handleMapRequestAsByteArray(mapRequestPacket);
810 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
811 assertEquals(Ipv4BinaryAfi.class, captor.getValue().getMapRequest().getSourceEid().getEid().getAddressType());
817 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
818 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
819 mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
823 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
825 assertEquals(28, result.length);
827 byte expectedLispMessageType = 2;
828 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
829 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
831 byte expectedRecordCount = (byte) 1;
832 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
834 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
835 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
836 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
837 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
842 public void mapReply_q_VerifyBasicIPv6() throws Exception {
843 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
847 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
849 assertEquals(40, result.length);
851 byte expectedRecordCount = (byte) 1;
852 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
854 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
855 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
856 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
857 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
859 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
864 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
865 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
866 mappingRecordBuilder.getLocatorRecord().add(
867 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
871 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
873 assertEquals(64, result.length);
875 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
876 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
878 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
879 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
884 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
887 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).recipient().getPort());
892 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
893 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
894 mappingRecordBuilder.getLocatorRecord().add(
895 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
898 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
899 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
904 public void mapReply__WithSingleLocator() throws Exception {
905 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
906 mappingRecordBuilder.getLocatorRecord().add(
907 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
910 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
911 assertEquals(40, result.length);
913 byte expectedLocCount = 1;
914 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
916 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
918 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
919 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
924 public void mapReply__WithMultipleLocator() throws Exception {
925 mappingRecordBuilder.getLocatorRecord().add(
926 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
927 mappingRecordBuilder.getLocatorRecord().add(
928 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1"))
932 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
933 assertEquals(64, result.length);
935 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
937 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
938 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
939 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
941 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
943 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
944 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
945 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
947 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
951 public void handleUnknownLispMessage() throws Exception {
952 // IP: 192.168.136.10 -> 128.223.156.35
953 // UDP: 49289 -> 4342
954 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
956 byte[] unknownTypePacket = extractWSUdpByteArray(
957 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
958 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
959 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
960 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
961 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
962 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
963 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
964 assertNull(handlePacket(unknownTypePacket));
968 public void mapRequest__MultipleItrRlocs() throws Exception {
969 // this is what LISPmob sends when configured multiple RLOCs for single
971 // ITR-RLOC 1: 10.1.0.111
972 // ITR-RLOC 2: 192.168.136.51
974 mapRequestPacket = extractWSUdpByteArray(
975 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
976 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 "
977 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 "
978 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 "
979 + "0040 08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 "
980 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 "
981 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 "
982 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 "
983 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 "
984 + "0090 00 05 00 01 c0 a8 88 33");
986 handleMapRequestAsByteArray(mapRequestPacket);
987 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any(RequestMapping.class));
990 private void stubHandleRequest() {
992 allowing(contextMockLispSouthboundPlugin).sendNotificationIfPossible(wany(Notification.class));
993 } catch (InterruptedException e) {
994 LOG.debug("Interrupted", e);
998 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
999 handleMapRequestPacket(inPacket);
1000 return lastMapReplyPacket().content().array();
1003 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
1004 handleMapRegisterPacket(inPacket);
1005 return lastMapNotifyPacket().content().array();
1008 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
1009 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1010 new InetSocketAddress(0));
1011 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1012 // This is till not the real port number, but it's better
1013 //dp.setPort(LispMessage.PORT_NUM);
1014 testedLispService.handlePacket(dp);
1015 return lastMapReplyPacket();
1018 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
1019 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1020 new InetSocketAddress(0));
1021 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1022 // This is till not the real port number, but it's better
1023 //dp.setPort(LispMessage.PORT_NUM);
1024 testedLispService.handlePacket(dp);
1025 if (mapNotifyBuilder == null) {
1028 return lastMapNotifyPacket();
1032 private DatagramPacket handlePacket(byte[] inPacket) {
1033 // TODO get from mock
1034 testedLispService.handlePacket(new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1035 new InetSocketAddress(0)));
1039 private byte[] extractWSUdpByteArray(String wiresharkHex) {
1040 final int headerLen = 42;
1041 byte[] res = new byte[1000];
1042 String[] split = wiresharkHex.split(" ");
1044 for (String cur : split) {
1046 if (cur.length() == 2) {
1048 if (counter > headerLen) {
1049 res[counter - headerLen - 1] = (byte) Integer.parseInt(cur, 16);
1054 return Arrays.copyOf(res, counter - headerLen);
1057 @Test(expected = LispMalformedPacketException.class)
1058 public void mapRequest__NoIpItrRloc() throws Exception {
1059 mapRequestPacket = hexToByteBuffer("10 00 "
1060 // This means 3 ITR - RLOCs
1062 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 "
1063 // MAC (ITR-RLOC #1 of 3)
1064 + "40 05 c0 a8 88 0a 01 02 "
1065 // MAC (ITR-RLOC #2 of 3)
1066 + "40 05 00 00 00 00 00 00 "
1067 // MAC (ITR-RLOC #3 of 3)
1068 + "40 05 11 22 34 56 78 90 "
1069 + "00 20 00 01 01 02 03 04").array();
1070 handleMapRequestPacket(mapRequestPacket);