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.lispflowmapping.lisp.serializer.MapNotifySerializer;
43 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
44 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
45 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
46 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
47 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
48 import org.opendaylight.lispflowmapping.mapcache.AuthKeyDb;
49 import org.opendaylight.lispflowmapping.southbound.ConcurrentLispSouthboundStats;
50 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
51 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterCache;
52 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
53 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
54 import org.opendaylight.mdsal.binding.api.DataBroker;
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;
118 public static void initTests() {
119 akdb = Mockito.mock(AuthKeyDb.class);
120 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
122 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
123 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
124 "2610:d0:ffff:192:0:0:0:1/128"))))
125 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
126 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
127 "153.16.254.1/32"))))
128 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
129 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
130 "125.124.123.122/8", new InstanceIdType(21L)))))
131 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
132 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asMacEid(
133 "0a:0b:0c:0d:0e:0f"))))
134 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
135 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
136 "f0f:f0f:f0f:f0f:f0f:f0f:f0f:f0f/8"))))
137 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
138 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
140 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
142 akdl = Mockito.mock(AuthenticationKeyDataListener.class);
143 Mockito.when(akdl.authKeysForEidsUnchanged(Mockito.anyMap(), Mockito.anyLong())).thenReturn(true);
148 public void before() throws Exception {
150 mockLispSouthboundPlugin = Mockito.mock(LispSouthboundPlugin.class);
151 contextMockLispSouthboundPlugin = context.mock(LispSouthboundPlugin.class);
152 Mockito.when(mockLispSouthboundPlugin.isMapRegisterCacheEnabled()).thenReturn(true);
153 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCacheTimeout()).thenReturn(CACHE_RECORD_TIMEOUT);
154 mapRegisterCache = new MapRegisterCache();
155 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
156 Mockito.when(mockLispSouthboundPlugin.getDataBroker()).thenReturn(Mockito.mock(DataBroker.class));
157 Mockito.when(mockLispSouthboundPlugin.getAkdb()).thenReturn(akdb);
158 Mockito.when(mockLispSouthboundPlugin.getAuthenticationKeyDataListener()).thenReturn(akdl);
159 ConcurrentLispSouthboundStats lispSouthboundStats = new ConcurrentLispSouthboundStats();
160 Mockito.when(mockLispSouthboundPlugin.getStats()).thenReturn(lispSouthboundStats);
161 testedLispService = new LispSouthboundHandler(mockLispSouthboundPlugin);
163 // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
164 // LISP(Type = 8 - Encapsulated)
165 // IP: 192.168.136.10 -> 1.2.3.4
167 // LISP(Type = 1 Map-Request
171 // Source EID not present
172 // Nonce: 0x3d8d2acd39c8d608
173 // ITR-RLOC AFI=1 Address=192.168.136.10
174 // Record 1: 1.2.3.4/32
175 mapRequestPacket = extractWSUdpByteArray(
176 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
177 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
178 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
179 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
180 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
181 + "0050 2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 c0 a8 88 0a 00 20 "
182 + "0060 00 01 01 02 03 04");
183 mapReplyBuilder = new MapReplyBuilder();
184 mapReplyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
185 mapReplyBuilder.setNonce((long) 0);
186 mapReplyBuilder.setEchoNonceEnabled(false);
187 mapReplyBuilder.setProbe(true);
188 mapReplyBuilder.setSecurityEnabled(true);
189 mappingRecordBuilder = new MappingRecordBuilder();
190 String ip = "0.0.0.0";
191 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid(ip + "/0"));
192 mappingRecordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
193 mappingRecordBuilder.setRecordTtl(10);
194 mappingRecordBuilder.setMapVersion((short) 0);
195 mappingRecordBuilder.setAction(Action.NativelyForward);
196 mappingRecordBuilder.setAuthoritative(false);
197 // eidToLocatorBuilder.setPrefix(new LispIpv4Address(0));
198 // mapReply.addEidToLocator(eidToLocatorBuilder);
200 // IP: 192.168.136.10 -> 128.223.156.35
201 // UDP: 49289 -> 4342
202 // LISP(Type = 3 Map-Register, P=1, M=1
206 // AuthDataLength: 20 Data:
207 // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
208 // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
210 // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
211 // Priority/Weight: 1/100, Multicast Priority/Weight:
215 mapRegisterPacket = extractWSUdpByteArray(
216 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
217 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
218 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
219 + "0030 00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
220 + "0040 71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
221 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
222 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
223 mapNotifyBuilder = new MapNotifyBuilder();
224 mapNotifyBuilder.setAuthenticationData(new byte[0]);
229 public void todos() throws Exception {
231 // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
232 // TODO: Non-Encapsulated packets
235 @Test(expected = LispMalformedPacketException.class)
236 public void mapRegister__IllegalPacket() throws Exception {
237 mapRegisterPacket = extractWSUdpByteArray(
238 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
239 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
240 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 ");
242 handleMapRegisterPacket(mapRegisterPacket);
245 @Test(expected = LispMalformedPacketException.class)
246 public void mapRequest__IllegalPacket() throws Exception {
247 mapRequestPacket = extractWSUdpByteArray(
248 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
249 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
250 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
251 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
252 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d ");
253 handleMapRequestPacket(mapRequestPacket);
256 @Test(expected = LispMalformedPacketException.class)
257 public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
258 mapRequestPacket = extractWSUdpByteArray(
259 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
260 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
261 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 ");
262 handleMapRequestPacket(mapRequestPacket);
266 public void mapRegister__TwoRlocs() throws Exception {
268 // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
269 // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
270 // Priority/Weight: 255/0
271 // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
272 // Multicast Priority/Weight: 255/0
273 mapRegisterPacket = extractWSUdpByteArray(
274 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
275 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
276 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "
277 + "0030 00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 "
278 + "0040 e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 "
279 + "0050 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 "
280 + "0060 ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 "
281 + "0070 00 01 c0 a8 88 33");
283 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
284 handleMapRegisterPacket(mapRegisterPacket);
285 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
287 List<MappingRecordItem> eidRecords = captor.getValue().getMapRegister().getMappingRecordItem();
288 assertEquals(1, eidRecords.size());
289 MappingRecord eidRecord = eidRecords.get(0).getMappingRecord();
290 assertEquals(2, eidRecord.getLocatorRecord().size());
291 assertEquals(LispAddressUtil.asIpv4Rloc("10.1.0.110"), eidRecord.getLocatorRecord().get(0).getRloc());
292 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.51"), eidRecord.getLocatorRecord().get(1).getRloc());
296 public void mapRegister__Ipv6Rloc() throws Exception {
297 // P bit (Proxy-Map-Reply): Set
298 // M bit (Want-Map-Notify): Set
303 // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
304 // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
306 // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
307 // Priority/Weight: 255/0
309 mapRegisterPacket = extractWSUdpByteArray(
310 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
311 + "0010 00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 "
312 + "0020 01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 "
313 + "0030 00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 "
314 + "0040 0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 "
315 + "0050 00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff "
316 + "0060 01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 "
317 + "0070 00 01 0a 00 3a 9c");
319 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
320 handleMapRegisterPacket(mapRegisterPacket);
321 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
322 MappingRecord eidToLocatorRecord =
323 captor.getValue().getMapRegister().getMappingRecordItem().get(0).getMappingRecord();
325 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:1/128"),
326 eidToLocatorRecord.getEid());
327 assertEquals(Ipv6PrefixBinaryAfi.class, eidToLocatorRecord.getEid().getAddressType());
329 assertEquals(LispAddressUtil.asIpv4Rloc("10.0.58.156"), eidToLocatorRecord.getLocatorRecord().get(0).getRloc());
333 public void mapRegister__VerifyBasicFields() throws Exception {
334 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
335 handleMapRegisterPacket(mapRegisterPacket);
336 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
337 MappingRecord eidToLocator =
338 captor.getValue().getMapRegister().getMappingRecordItem().get(0).getMappingRecord();
340 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"), eidToLocator.getEid());
341 assertEquals(1, eidToLocator.getLocatorRecord().size());
342 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.10"), eidToLocator.getLocatorRecord().get(0).getRloc());
346 public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
347 mapNotifyBuilder = null;
348 assertNull(handleMapRegisterPacket(mapRegisterPacket));
352 public void mapRegister__NonSetMBit() throws Exception {
353 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
354 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
355 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
356 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
357 + "0030 00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
358 + "0040 83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 "
359 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
360 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
362 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
363 handleMapRegisterPacket(registerWithNonSetMBit);
364 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
365 assertFalse(captor.getValue().getMapRegister().isWantMapNotify());
369 public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
370 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
371 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
372 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
373 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
374 + "0030 00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
375 + "0040 e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
376 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
377 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
379 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
380 handleMapRegisterPacket(registerWithNonSetMBit);
381 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
382 assertFalse(captor.getValue().getMapRegister().isWantMapNotify());
386 public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
387 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
388 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
389 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
390 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
391 + "0030 00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
392 + "0040 4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
393 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
394 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
396 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
397 handleMapRegisterPacket(registerWithNonSetMBit);
398 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
399 assertTrue(captor.getValue().getMapRegister().isWantMapNotify());
403 * Tests whether handling of map-register message will generate mapping-keep-alive notification.
406 public void mapRegister_isMappingKeepAliveAndMapNotifyGenerated() throws InterruptedException,
407 UnknownHostException {
408 byte[] eidPrefixAfi = new byte[] {
413 byte[] eidPrefix = new byte[] {
415 0x0a, 0x0a, 0x0a, 0x0a
418 //send stream of byte -> map register message
419 InOrder inOrder = Mockito.inOrder(mockLispSouthboundPlugin);
420 final MapRegisterCacheKey cacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
421 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(cacheKey, mapRegisterCache);
422 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
423 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
424 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
425 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
426 cacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
428 //sending the same byte stream -> map register second time
429 captor = ArgumentCaptor.forClass(AddMapping.class);
430 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
431 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
433 //mapping-keep-alive message should be generated
434 MapRegisterCacheTestUtil.afterSecondMapRegisterInvocationValidation(
435 mockLispSouthboundPlugin, eidPrefixAfi, eidPrefix);
438 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix) {
439 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
442 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) {
443 final byte[] mapRegisterMessage = MapRegisterCacheTestUtil.joinArrays(DATA1, NONCE, KEY_ID,
444 authenticationData, DATA2, eidPrefixAfi, eidPrefix, DATA3, XTR_ID, SITE_ID);
445 handlePacket(mapRegisterMessage);
449 * It tests whether map register message is stored to local cache with Ipv4 EidPrefix.
452 public void mapRegister_cacheWithEidPrefixIpv4Test() throws InterruptedException {
453 byte[] eidPrefixAfi = new byte[] {
458 byte[] eidPrefix = new byte[] {
460 0x0a, 0x0a, 0x0a, 0x0a
463 cacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
467 * It tests whether map register message is stored to local cache with Ipv6 EidPrefix.
470 public void mapRegister_cacheWithEidPrefixIpv6Test() throws InterruptedException {
471 byte[] eidPrefixAfi = new byte[] {
476 byte[] eidPrefix = new byte[] {
478 0x0f, 0x0f, 0x0f, 0x0f,
480 0x0f, 0x0f, 0x0f, 0x0f,
482 0x0f, 0x0f, 0x0f, 0x0f,
484 0x0f, 0x0f, 0x0f, 0x0f
487 byte[] authenticationData = new byte[] {
489 0x41,(byte)0x83,0x13,0x7C,
490 0x48,(byte)0xEE,0x75,(byte)0x9A,
491 0x4,(byte)0x8C,0x46,(byte)0xA6,
492 0x1B,0x13,(byte)0xC8,0x4D,
493 (byte)0xA1,0x17,0x53,(byte)0xC3
496 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
500 * It tests whether map register message is stored to local cache with Mac 48bits EidPrefix.
503 public void mapRegister_cacheWithEidPrefixMac48Test() throws InterruptedException {
504 byte[] eidPrefixAfi = new byte[] {
509 byte[] eidPrefix = new byte[] {
511 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
514 byte[] authenticationData = new byte[] {
516 (byte)0xB2,(byte)0x8E,0x6,(byte)0x9D,
517 0x61,(byte)0xD8,0xC,0x24,
518 (byte)0x80,0x61,0x5A,0x20,
519 0xD,0x50,0x5E,(byte)0xAE,
520 0x47,(byte)0xF7,(byte)0x86,0x36
522 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
526 * It tests whether map register message is stored to local cache with Lcaf EidPrefix (inside Ipv4).
529 public void mapRegister_cacheWithEidPrefixLcafTest() throws InterruptedException {
530 byte[] eidPrefixAfi = new byte[] {
535 //following lcaf prefixed variables are defined according to https://tools.ietf
536 // .org/html/draft-ietf-lisp-lcaf-12#section-4.1
537 byte[] lcafRsvd1 = new byte[]{0x00};
538 byte[] lcafFlags = new byte[]{0x00};
539 byte[] lcafType = new byte[]{0x02};
540 byte[] lcafIIDMaskLength = new byte[]{0x20};
541 byte[] lcafLength = new byte[] {0x00, 0x0a};
542 byte[] lcafInstanceId = new byte[]{0x00, 0x00, 0x00, 0x15};
543 byte[] lcafAfi = new byte[] {0x00, 0x01};
544 byte[] lcafAddress = new byte[] {0x7d, 0x7c, 0x7b, 0x7a};
546 byte[] eidPrefix = joinArrays(lcafRsvd1, lcafFlags, lcafType, lcafIIDMaskLength, lcafLength, lcafInstanceId,
547 lcafAfi, lcafAddress);
549 byte[] authenticationData = new byte[] {
550 //authentication data length
553 0x68, 0x1d, (byte) 0x9e, 0x6e,
555 0x5e, 0x32, (byte) 0x88, 0x1a,
557 (byte) 0xae, 0x6b, (byte) 0xe3, 0x40,
559 0x30, (byte) 0x0b, (byte) 0xb6, (byte) 0xa0,
561 0x71, (byte) 0xf4, (byte) 0x8c, 0x5f
565 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
569 * It tests whether map register message is stored to local cache.
571 public void cacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) throws
572 InterruptedException {
573 final MapRegisterCacheKey mapRegisterCacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
575 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(mapRegisterCacheKey, mapRegisterCache);
576 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
577 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, authenticationData);
578 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
579 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
580 mapRegisterCacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
585 Checks whether old record from cache will expire and is replaced with new record.
587 add to empty cache record with timestamp older then 90 second - one object
588 add the same entry through calling of handleMapRegister
589 check that removeEntry() and addEntry() (or refreshEntry() was called on mocked object for mapRegisterCache
592 public void mapRegister_cacheRecordExpirationTest() throws InterruptedException {
593 //tests handling of map register message when next message comes:
595 //after cache entry timeout
596 cacheRecordExpirationTest(true);
598 //before cache entry timout
599 cacheRecordExpirationTest(false);
602 private void cacheRecordExpirationTest(boolean cacheRecordTimeouted) throws InterruptedException {
603 mapRegisterCache = Mockito.mock(MapRegisterCache.class);
604 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
606 final byte[] eidPrefixAfi = new byte[] {0x00, 0x01};
607 final byte[] eidPrefix = new byte[] {0x0a, 0x0a, 0x0a, 0x0a};
609 MapRegisterCacheKeyBuilder cacheKeyBld = new MapRegisterCacheKeyBuilder();
610 cacheKeyBld.setXtrId(XTR_ID);
611 cacheKeyBld.setEidPrefix(eidPrefix);
612 cacheKeyBld.setSiteId(SITE_ID);
614 MapRegisterCacheMetadataBuilder cacheMetadataBld = new MapRegisterCacheMetadataBuilder();
615 cacheMetadataBld.setTimestamp(System.currentTimeMillis() - (cacheRecordTimeouted ? CACHE_RECORD_TIMEOUT : 0L));
616 cacheMetadataBld.setWantMapNotify(false);
617 cacheMetadataBld.setEidLispAddress(new ArrayList<>());
619 MapRegisterCacheValueBuilder cacheValueBld = new MapRegisterCacheValueBuilder();
620 cacheValueBld.setMapRegisterCacheMetadata(cacheMetadataBld.build());
621 cacheValueBld.setPacketData(MapRegisterCacheTestUtil.joinArrays(DATA1, KEY_ID, DATA2, eidPrefixAfi,
622 eidPrefix, DATA3, XTR_ID, SITE_ID));
625 final MapRegisterCacheKey cacheKey = cacheKeyBld.build();
626 final MapRegisterCacheValue cacheValue = cacheValueBld.build();
628 Mockito.when(mapRegisterCache.getEntry(Mockito.eq(cacheKey))).thenReturn(cacheRecordTimeouted ? null :
630 Mockito.when(mapRegisterCache.refreshEntry(Mockito.eq(cacheKey))).thenReturn(cacheValue);
632 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
633 Mockito.verify(mockLispSouthboundPlugin, Mockito.atLeastOnce()).sendNotificationIfPossible(
634 Mockito.any(AddMapping.class));
636 InOrder inOrder = Mockito.inOrder(mapRegisterCache);
637 inOrder.verify(mapRegisterCache).getEntry(Mockito.eq(cacheKey));
639 if (cacheRecordTimeouted) {
640 inOrder.verify(mapRegisterCache).addEntry(Mockito.eq(cacheKey), AdditionalMatchers.not(Mockito.eq(
643 inOrder.verify(mapRegisterCache).refreshEntry(Mockito.eq(cacheKey));
649 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
650 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
651 extraDataPacket[mapRegisterPacket.length] = 0x9;
652 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
654 DatagramPacket dp = new DatagramPacket(wrappedBuffer(extraDataPacket), new InetSocketAddress(0),
655 new InetSocketAddress(0));
656 testedLispService.handlePacket(dp);
657 // Check map register fields.
659 // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
660 byte[] notifyResult = lastMapNotifyPacket().content().array();
661 assertEquals(mapRegisterPacket.length, notifyResult.length);
665 private DatagramPacket lastMapReplyPacket() {
666 ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
667 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
670 private DatagramPacket lastMapNotifyPacket() {
671 if (mapNotifyBuilder.getMappingRecordItem() == null) {
672 mapNotifyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
674 mapNotifyBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
675 mappingRecordBuilder.build()).build());
676 mapNotifyBuilder.setNonce((long) 0);
677 mapNotifyBuilder.setKeyId((short) 0);
678 mapNotifyBuilder.setAuthenticationData(new byte[0]);
679 ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotifyBuilder.build());
680 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
685 public void mapNotify__VerifyBasicFields() throws Exception {
686 byte registerType = mapRegisterPacket[0];
687 assertEquals(MessageType.MapRegister.getIntValue(), registerType >> 4);
689 byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
691 assertEquals(mapRegisterPacket.length, result.length);
693 byte expectedType = (byte) (MessageType.MapNotify.getIntValue() << 4);
694 assertHexEquals(expectedType, result[0]);
695 assertHexEquals((byte) 0x00, result[1]);
696 assertHexEquals((byte) 0x00, result[2]);
698 byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(
699 Arrays.copyOfRange(mapRegisterPacket, 3, 16),
700 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
701 byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
702 Arrays.copyOfRange(result, 36, result.length));
703 ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData,
704 notifyWithoutTypeWithOutAuthenticationData);
709 public void mapNotify__VerifyPort() throws Exception {
710 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
711 assertEquals(LispMessage.PORT_NUM, notifyPacket.recipient().getPort());
715 public void mapRequest__VerifyBasicFields() throws Exception {
716 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
717 handleMapRequestAsByteArray(mapRequestPacket);
718 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
719 List<EidItem> eids = captor.getValue().getMapRequest().getEidItem();
720 assertEquals(1, eids.size());
721 Eid lispAddress = eids.get(0).getEid();
722 assertEquals(Ipv4PrefixBinaryAfi.class, lispAddress.getAddressType());
723 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32"), lispAddress);
724 assertEquals(0x3d8d2acd39c8d608L, captor.getValue().getMapRequest().getNonce().longValue());
728 public void mapRequest__Ipv6Eid() throws Exception {
729 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
730 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
731 // (2610:d0:ffff:192::2)
734 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
735 // ITR-RLOC 1: 10.0.58.156
736 // Record 1: 2610:d0:ffff:192::2/128
737 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
738 // Authoritative, No-Action
740 mapRequestPacket = extractWSUdpByteArray(
741 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
742 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
743 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
744 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
745 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
746 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
747 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
748 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
749 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
750 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
751 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
752 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
754 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
755 handleMapRequestAsByteArray(mapRequestPacket);
756 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
757 assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"),
758 captor.getValue().getMapRequest().getSourceEid().getEid());
759 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:2/128"),
760 captor.getValue().getMapRequest().getEidItem().get(0).getEid());
765 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
766 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
767 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
768 // (2610:d0:ffff:192::2)
769 // encapsulated UDP source port: 4342
771 mapRequestPacket = extractWSUdpByteArray(
772 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
773 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
774 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
775 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
776 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
777 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
778 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
779 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
780 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
781 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
782 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
783 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
785 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
786 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
787 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any());
788 assertEquals(4342, replyPacket.recipient().getPort());
792 public void mapRequest__WithSourceEid() throws Exception {
793 // encapsulated LISP packet
794 // Source EID = 153.16.254.1
796 mapRequestPacket = extractWSUdpByteArray(
797 "0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 "
798 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
799 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
800 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
801 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
802 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
803 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
804 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 "
805 + "0080 00 01 0a 00 01 26");
807 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
808 handleMapRequestAsByteArray(mapRequestPacket);
809 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
810 assertEquals(Ipv4BinaryAfi.class, captor.getValue().getMapRequest().getSourceEid().getEid().getAddressType());
816 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
817 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
818 mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
822 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
824 assertEquals(28, result.length);
826 byte expectedLispMessageType = 2;
827 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
828 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
830 byte expectedRecordCount = (byte) 1;
831 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
833 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
834 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
835 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
836 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
841 public void mapReply_q_VerifyBasicIPv6() throws Exception {
842 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
846 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
848 assertEquals(40, result.length);
850 byte expectedRecordCount = (byte) 1;
851 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
853 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
854 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
855 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
856 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
858 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
863 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
864 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
865 mappingRecordBuilder.getLocatorRecord().add(
866 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
870 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
872 assertEquals(64, result.length);
874 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
875 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
877 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
878 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
883 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
886 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).recipient().getPort());
891 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
892 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
893 mappingRecordBuilder.getLocatorRecord().add(
894 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
897 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
898 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
903 public void mapReply__WithSingleLocator() throws Exception {
904 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
905 mappingRecordBuilder.getLocatorRecord().add(
906 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
909 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
910 assertEquals(40, result.length);
912 byte expectedLocCount = 1;
913 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
915 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
917 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
918 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
923 public void mapReply__WithMultipleLocator() throws Exception {
924 mappingRecordBuilder.getLocatorRecord().add(
925 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
926 mappingRecordBuilder.getLocatorRecord().add(
927 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1"))
931 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
932 assertEquals(64, result.length);
934 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
936 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
937 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
938 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
940 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
942 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
943 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
944 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
946 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
950 public void handleUnknownLispMessage() throws Exception {
951 // IP: 192.168.136.10 -> 128.223.156.35
952 // UDP: 49289 -> 4342
953 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
955 byte[] unknownTypePacket = extractWSUdpByteArray(
956 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
957 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
958 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
959 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
960 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
961 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
962 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
963 assertNull(handlePacket(unknownTypePacket));
967 public void mapRequest__MultipleItrRlocs() throws Exception {
968 // this is what LISPmob sends when configured multiple RLOCs for single
970 // ITR-RLOC 1: 10.1.0.111
971 // ITR-RLOC 2: 192.168.136.51
973 mapRequestPacket = extractWSUdpByteArray(
974 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
975 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 "
976 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 "
977 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 "
978 + "0040 08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 "
979 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 "
980 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 "
981 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 "
982 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 "
983 + "0090 00 05 00 01 c0 a8 88 33");
985 handleMapRequestAsByteArray(mapRequestPacket);
986 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any(RequestMapping.class));
989 private void stubHandleRequest() {
991 allowing(contextMockLispSouthboundPlugin).sendNotificationIfPossible(wany(Notification.class));
992 } catch (InterruptedException e) {
993 LOG.debug("Interrupted", e);
997 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
998 handleMapRequestPacket(inPacket);
999 return lastMapReplyPacket().content().array();
1002 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
1003 handleMapRegisterPacket(inPacket);
1004 return lastMapNotifyPacket().content().array();
1007 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
1008 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1009 new InetSocketAddress(0));
1010 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1011 // This is till not the real port number, but it's better
1012 //dp.setPort(LispMessage.PORT_NUM);
1013 testedLispService.handlePacket(dp);
1014 return lastMapReplyPacket();
1017 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
1018 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1019 new InetSocketAddress(0));
1020 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1021 // This is till not the real port number, but it's better
1022 //dp.setPort(LispMessage.PORT_NUM);
1023 testedLispService.handlePacket(dp);
1024 if (mapNotifyBuilder == null) {
1027 return lastMapNotifyPacket();
1031 private DatagramPacket handlePacket(byte[] inPacket) {
1032 // TODO get from mock
1033 testedLispService.handlePacket(new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1034 new InetSocketAddress(0)));
1038 private byte[] extractWSUdpByteArray(String wiresharkHex) {
1039 final int headerLen = 42;
1040 byte[] res = new byte[1000];
1041 String[] split = wiresharkHex.split(" ");
1043 for (String cur : split) {
1045 if (cur.length() == 2) {
1047 if (counter > headerLen) {
1048 res[counter - headerLen - 1] = (byte) Integer.parseInt(cur, 16);
1053 return Arrays.copyOf(res, counter - headerLen);
1056 @Test(expected = LispMalformedPacketException.class)
1057 public void mapRequest__NoIpItrRloc() throws Exception {
1058 mapRequestPacket = hexToByteBuffer("10 00 "
1059 // This means 3 ITR - RLOCs
1061 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 "
1062 // MAC (ITR-RLOC #1 of 3)
1063 + "40 05 c0 a8 88 0a 01 02 "
1064 // MAC (ITR-RLOC #2 of 3)
1065 + "40 05 00 00 00 00 00 00 "
1066 // MAC (ITR-RLOC #3 of 3)
1067 + "40 05 11 22 34 56 78 90 "
1068 + "00 20 00 01 01 02 03 04").array();
1069 handleMapRequestPacket(mapRequestPacket);