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 com.google.common.base.Preconditions;
13 import io.netty.buffer.ByteBufUtil;
14 import io.netty.channel.ChannelHandler;
15 import io.netty.channel.ChannelHandlerContext;
16 import io.netty.channel.SimpleChannelInboundHandler;
17 import io.netty.channel.socket.DatagramPacket;
19 import java.net.InetAddress;
20 import java.nio.ByteBuffer;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
25 import java.util.Objects;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
29 import org.opendaylight.lispflowmapping.dsbackend.DataStoreBackEnd;
30 import org.opendaylight.lispflowmapping.inmemorydb.HashMapDb;
31 import org.opendaylight.lispflowmapping.lisp.authentication.ILispAuthentication;
32 import org.opendaylight.lispflowmapping.lisp.authentication.LispAuthenticationUtil;
33 import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
34 import org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer;
35 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
36 import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer;
37 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
38 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
39 import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
40 import org.opendaylight.lispflowmapping.lisp.util.MapRequestUtil;
41 import org.opendaylight.lispflowmapping.mapcache.SimpleMapCache;
42 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
43 import org.opendaylight.lispflowmapping.southbound.LispSouthboundStats;
44 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterCache;
45 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterPartialDeserializer;
46 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
47 import org.opendaylight.lispflowmapping.southbound.lisp.network.PacketHeader;
48 import org.opendaylight.lispflowmapping.southbound.util.LispNotificationHelper;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMappingBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapNotifyBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapReplyBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAlive;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAliveBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMappingBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadata;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddress;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddressBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValue;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValueBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.transport.address.TransportAddressBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.AuthenticationKey;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
74 import org.opendaylight.yangtools.yang.binding.Notification;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
78 @ChannelHandler.Sharable
79 public class LispSouthboundHandler extends SimpleChannelInboundHandler<DatagramPacket>
80 implements ILispSouthboundService, AutoCloseable {
81 private MapRegisterCache mapRegisterCache;
82 private boolean mapRegisterCacheEnabled = true;
85 * How long is record supposed to be relevant. After this time record isn't valid.
87 * If you modify this value, please update the LispSouthboundServiceTest class too.
89 private static final long CACHE_RECORD_TIMEOUT = 90000;
90 private DataBroker dataBroker;
92 private NotificationPublishService notificationPublishService;
93 protected static final Logger LOG = LoggerFactory.getLogger(LispSouthboundHandler.class);
95 //TODO: think whether this field can be accessed through mappingservice or some other configuration parameter
96 private boolean authenticationEnabled = true;
98 private final LispSouthboundPlugin lispSbPlugin;
99 private LispSouthboundStats lispSbStats = null;
100 private SimpleMapCache smc;
101 private AuthenticationKeyDataListener authenticationKeyDataListener;
102 private DataStoreBackEnd dsbe;
103 private boolean isReadFromChannelEnabled = true;
105 public LispSouthboundHandler(LispSouthboundPlugin lispSbPlugin) {
106 this.lispSbPlugin = lispSbPlugin;
107 if (lispSbPlugin != null) {
108 this.lispSbStats = lispSbPlugin.getStats();
110 this.mapRegisterCache = new MapRegisterCache();
111 this.smc = new SimpleMapCache(new HashMapDb());
114 public void handlePacket(DatagramPacket msg) {
115 ByteBuffer inBuffer = msg.content().nioBuffer();
116 int type = ByteUtil.getUnsignedByte(inBuffer, LispMessage.Pos.TYPE) >> 4;
118 Object lispType = MessageType.forValue(type);
119 if (lispType == MessageType.EncapsulatedControlMessage) {
120 LOG.trace("Received packet of type Encapsulated Control Message");
121 handleEncapsulatedControlMessage(inBuffer, msg.sender().getAddress());
122 } else if (lispType == MessageType.MapRequest) {
123 LOG.trace("Received packet of type Map-Request");
124 handleMapRequest(inBuffer, msg.sender().getPort());
125 } else if (lispType == MessageType.MapRegister) {
126 LOG.trace("Received packet of type Map-Register");
127 handleMapRegister(inBuffer, msg.sender().getAddress(), msg.sender().getPort());
128 } else if (lispType == MessageType.MapNotify) {
129 LOG.trace("Received packet of type Map-Notify");
130 handleMapNotify(inBuffer, msg.sender().getAddress(), msg.sender().getPort());
131 } else if (lispType == MessageType.MapReply) {
132 LOG.trace("Received packet of type Map-Reply");
133 handleMapReply(inBuffer, msg.sender().getAddress(), msg.sender().getPort());
135 LOG.warn("Received unknown LISP control packet (type " + ((lispType != null) ? lispType : type) + ")");
139 private void handleEncapsulatedControlMessage(ByteBuffer inBuffer, InetAddress sourceAddress) {
141 handleMapRequest(inBuffer, extractEncapsulatedSourcePort(inBuffer));
142 } catch (RuntimeException re) {
143 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len="
144 + inBuffer.capacity() + ")", re);
148 private void handleMapRequest(ByteBuffer inBuffer, int port) {
150 MapRequest request = MapRequestSerializer.getInstance().deserialize(inBuffer);
151 InetAddress finalSourceAddress = MapRequestUtil.selectItrRloc(request);
152 if (finalSourceAddress == null) {
153 throw new LispMalformedPacketException("Couldn't deserialize Map-Request, no ITR Rloc found!");
156 RequestMappingBuilder requestMappingBuilder = new RequestMappingBuilder();
157 requestMappingBuilder.setMapRequest(LispNotificationHelper.convertMapRequest(request));
158 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
159 transportAddressBuilder.setIpAddress(
160 LispNotificationHelper.getIpAddressBinaryFromInetAddress(finalSourceAddress));
161 transportAddressBuilder.setPort(new PortNumber(port));
162 requestMappingBuilder.setTransportAddress(transportAddressBuilder.build());
163 if (notificationPublishService != null) {
164 notificationPublishService.putNotification(requestMappingBuilder.build());
165 LOG.trace("MapRequest was published!");
167 LOG.warn("Notification Provider is null!");
169 } catch (RuntimeException re) {
170 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len="
171 + inBuffer.capacity() + ")", re);
172 } catch (InterruptedException e) {
173 LOG.warn("Notification publication interrupted!");
177 private int extractEncapsulatedSourcePort(ByteBuffer inBuffer) {
179 inBuffer.position(PacketHeader.Length.LISP_ENCAPSULATION);
180 int ipType = (inBuffer.get() >> 4);
182 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV4 - 1);
183 } else if (ipType == 6) {
184 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV6_NO_EXT - 1);
186 throw new LispMalformedPacketException(
187 "Couldn't deserialize Map-Request: inner packet has unknown IP version: " + ipType);
190 int encapsulatedSourcePort = inBuffer.getShort() & 0xFFFF;
191 inBuffer.position(inBuffer.position() + PacketHeader.Length.UDP - 2);
192 return encapsulatedSourcePort;
193 } catch (RuntimeException re) {
194 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len="
195 + inBuffer.capacity() + ")", re);
199 private void handleMapRegister(ByteBuffer inBuffer, InetAddress sourceAddress, int port) {
201 Map.Entry<MapRegisterCacheKey, byte[]> artificialEntry = null;
202 MapRegisterCacheKey cacheKey = null;
203 MapRegisterCacheValue cacheValue = null;
204 if (mapRegisterCacheEnabled) {
205 artificialEntry = MapRegisterPartialDeserializer.deserializePartially(inBuffer, sourceAddress);
206 cacheKey = artificialEntry == null ? null : artificialEntry.getKey();
207 cacheValue = resolveCacheValue(artificialEntry);
209 if (cacheValue != null) {
210 MapRegisterCacheMetadata mapRegisterMeta = cacheValue.getMapRegisterCacheMetadata();
211 LOG.debug("Map register message site-ID: {} xTR-ID: {} from cache.", mapRegisterMeta.getSiteId(),
212 mapRegisterMeta.getXtrId());
213 cacheValue = refreshEntry(cacheKey);
214 if (cacheValue != null) {
215 sendNotificationIfPossible(createMappingKeepAlive(cacheValue));
216 if (cacheValue.getMapRegisterCacheMetadata().isWantMapNotify()) {
217 sendMapNotifyMsg(inBuffer, sourceAddress, port, cacheValue);
220 lispSbStats.incrementCacheHits();
222 MapRegister mapRegister = MapRegisterSerializer.getInstance().deserialize(inBuffer, sourceAddress);
223 final MappingAuthkey mappingAuthkey = tryToAuthenticateMessage(mapRegister, inBuffer);
224 if (mappingAuthkey != null) {
225 AddMappingBuilder addMappingBuilder = new AddMappingBuilder();
226 addMappingBuilder.setMapRegister(LispNotificationHelper.convertMapRegister(mapRegister));
227 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
228 transportAddressBuilder.setIpAddress(LispNotificationHelper.getIpAddressBinaryFromInetAddress(
230 transportAddressBuilder.setPort(new PortNumber(port));
231 addMappingBuilder.setTransportAddress(transportAddressBuilder.build());
232 sendNotificationIfPossible(addMappingBuilder.build());
233 if (artificialEntry != null) {
234 final MapRegisterCacheMetadataBuilder cacheMetadataBldNew = new
235 MapRegisterCacheMetadataBuilder();
236 cacheMetadataBldNew.setEidLispAddress(provideEidPrefixesFromMessage(mapRegister));
237 cacheMetadataBldNew.setXtrId(mapRegister.getXtrId());
238 cacheMetadataBldNew.setSiteId(mapRegister.getSiteId());
239 cacheMetadataBldNew.setWantMapNotify(mapRegister.isWantMapNotify());
240 cacheMetadataBldNew.setMergeEnabled(mapRegister.isMergeEnabled());
241 cacheMetadataBldNew.setTimestamp(System.currentTimeMillis());
243 final MapRegisterCacheValueBuilder cacheValueBldNew = new MapRegisterCacheValueBuilder();
244 cacheValueBldNew.setPacketData(artificialEntry.getValue());
245 cacheValueBldNew.setMappingAuthkey(mappingAuthkey);
246 cacheValueBldNew.setMapRegisterCacheMetadata(cacheMetadataBldNew.build());
248 mapRegisterCache.addEntry(cacheKey, cacheValueBldNew.build());
251 lispSbStats.incrementCacheMisses();
253 } catch (RuntimeException re) {
254 throw new LispMalformedPacketException("Couldn't deserialize Map-Register (len="
255 + inBuffer.capacity() + ")", re);
256 } catch (InterruptedException e) {
257 LOG.warn("Notification publication interrupted!");
261 private MapRegisterCacheValue refreshEntry(final MapRegisterCacheKey cacheKey) {
262 MapRegisterCacheValue mapRegisterCacheValue = mapRegisterCache.refreshEntry(cacheKey);
263 if (mapRegisterCacheValue != null) {
264 mapRegisterCacheValue = refreshAuthKeyIfNecessary(mapRegisterCacheValue);
265 mapRegisterCache.addEntry(cacheKey, mapRegisterCacheValue);
266 return mapRegisterCacheValue;
271 private MapRegisterCacheValue refreshAuthKeyIfNecessary(MapRegisterCacheValue mapRegisterCacheValue) {
272 if (authenticationKeyDataListener.isAuthKeyRefreshing()) {
273 final boolean shouldAuthKeyRefreshingStop = System.currentTimeMillis() - authenticationKeyDataListener
274 .getAuthKeyRefreshingDate() > CACHE_RECORD_TIMEOUT;
275 if (shouldAuthKeyRefreshingStop) {
276 authenticationKeyDataListener.setAuthKeyRefreshing(false);
278 final MappingAuthkey mappingAuthkey = provideAuthenticateKey(mapRegisterCacheValue
279 .getMapRegisterCacheMetadata().getEidLispAddress());
281 final MapRegisterCacheValueBuilder newMapRegisterCacheValueBuilder = new MapRegisterCacheValueBuilder
282 (mapRegisterCacheValue);
283 final MapRegisterCacheMetadataBuilder newMapRegisterCacheMetadataBuilder =
284 new MapRegisterCacheMetadataBuilder(mapRegisterCacheValue.getMapRegisterCacheMetadata());
286 newMapRegisterCacheValueBuilder.setMappingAuthkey(mappingAuthkey);
287 newMapRegisterCacheValueBuilder.setMapRegisterCacheMetadata(newMapRegisterCacheMetadataBuilder.build());
288 return newMapRegisterCacheValueBuilder.build();
292 return mapRegisterCacheValue;
296 private MapRegisterCacheValue resolveCacheValue(Map.Entry<MapRegisterCacheKey, byte[]> entry) {
298 final MapRegisterCacheValue mapRegisterCacheValue = mapRegisterCache.getEntry(entry.getKey());
299 if (mapRegisterCacheValue != null) {
300 final long creationTime = mapRegisterCacheValue.getMapRegisterCacheMetadata().getTimestamp();
301 final long currentTime = System.currentTimeMillis();
302 if (currentTime - creationTime > CACHE_RECORD_TIMEOUT) {
303 mapRegisterCache.removeEntry(entry.getKey());
305 } else if (Arrays.equals(mapRegisterCacheValue.getPacketData(), entry.getValue())) {
306 return mapRegisterCacheValue;
313 private void sendNotificationIfPossible(final Notification notification) throws InterruptedException {
314 if (notificationPublishService != null) {
315 notificationPublishService.putNotification(notification);
316 LOG.trace("{} was published.", notification.getClass());
318 LOG.warn("Notification Provider is null!");
322 private MappingKeepAlive createMappingKeepAlive(final MapRegisterCacheValue value) {
323 MappingKeepAliveBuilder mappingKeepAliveBuilder = new MappingKeepAliveBuilder();
324 mappingKeepAliveBuilder.setMapRegisterCacheMetadata(value.getMapRegisterCacheMetadata());
325 return mappingKeepAliveBuilder.build();
329 * Returns null if not all of eids have the same value of authentication key
331 private MappingAuthkey provideAuthenticateKey(final List<EidLispAddress> eidLispAddresses) {
332 MappingAuthkey firstAuthKey = null;
333 for (int i = 0; i < eidLispAddresses.size(); i++) {
334 final Eid eid = eidLispAddresses.get(i).getEid();
336 firstAuthKey = smc.getAuthenticationKey(eid);
338 final MappingAuthkey authKey = smc.getAuthenticationKey(eid);
339 if (!Objects.equals(firstAuthKey, authKey)) {
348 private void sendMapNotifyMsg(final ByteBuffer inBuffer, final InetAddress inetAddress, int portNumber,
349 MapRegisterCacheValue mapRegisterValue) {
350 if (mapRegisterValue.getMappingAuthkey().getKeyType() != null) {
351 ByteBuffer outBuffer = transformMapRegisterToMapNotify(inBuffer);
352 if (mapRegisterValue.getMappingAuthkey().getKeyType() != 0) {
353 outBuffer = calculateAndSetNewMAC(outBuffer, mapRegisterValue.getMappingAuthkey().getKeyString());
355 outBuffer.position(0);
356 lispSbPlugin.handleSerializedLispBuffer(inetAddress, outBuffer, MessageType.MapNotify, portNumber);
358 LOG.error("Map-Register Cache: authentication succeeded, but can't find auth key for sending Map-Notify");
363 * Calculates new message authentication code (MAC) for notify message.
368 private ByteBuffer calculateAndSetNewMAC(final ByteBuffer buffer, final String authKey) {
369 final byte[] authenticationData = LispAuthenticationUtil.createAuthenticationData(buffer, authKey);
370 buffer.position(ILispAuthentication.MAP_REGISTER_AND_NOTIFY_AUTHENTICATION_POSITION);
371 buffer.put(authenticationData);
375 private ByteBuffer transformMapRegisterToMapNotify(final ByteBuffer buffer) {
377 byte typeAndFlags = buffer.get(0);
378 // Shift the xTR-ID present and built for an RTR bits to their correct position
379 byte flags = (byte) ((typeAndFlags << 2) & 0x0F);
380 // Set control message type to 4 (Map-Notify)
382 // Combine the nibbles
383 typeAndFlags = (byte) (type | flags);
384 byte[] byteReplacement = new byte[] {typeAndFlags, 0x00, 0x00};
385 buffer.put(byteReplacement);
390 private List<EidLispAddress> provideEidPrefixesFromMessage(final MapRegister mapRegister) {
391 List<EidLispAddress> eidsResult = new ArrayList<>();
392 for (MappingRecordItem mappingRecordItem : mapRegister.getMappingRecordItem()) {
393 final EidLispAddressBuilder eidLispAddressBuilder = new EidLispAddressBuilder();
394 final Eid eid = mappingRecordItem.getMappingRecord().getEid();
395 eidLispAddressBuilder.setEidLispAddressId(LispAddressStringifier.getString(eid));
396 eidLispAddressBuilder.setEid(eid);
397 eidsResult.add(eidLispAddressBuilder.build());
403 * Checks whether authentication data is valid.
405 * Methods pass through all records from map register message. For the EID of the first record it gets
406 * authentication key and does validation of authentication data again this authentication key. If it pass
407 * it just checks for remaining records (and its EID) whether they have the same authenticatin key stored in
408 * simple map cache (smc).
412 * @return Returns authentication key if all of EIDs have the same authentication key or null otherwise
414 private MappingAuthkey tryToAuthenticateMessage(final MapRegister mapRegister, final ByteBuffer byteBuffer) {
415 if (!authenticationEnabled) {
420 LOG.debug("Simple map cache wasn't instantieted and set.");
424 MappingAuthkey firstAuthKey = null;
425 final List<MappingRecordItem> mappingRecords = mapRegister.getMappingRecordItem();
426 for (int i = 0; i < mappingRecords.size(); i++) {
427 final MappingRecordItem recordItem = mappingRecords.get(i);
428 final MappingRecord mappingRecord = recordItem.getMappingRecord();
430 firstAuthKey = smc.getAuthenticationKey(mappingRecord.getEid());
431 if (!LispAuthenticationUtil.validate(mapRegister, byteBuffer, mappingRecord.getEid(), firstAuthKey)) {
435 final Eid eid = mappingRecord.getEid();
436 final MappingAuthkey authKey = smc.getAuthenticationKey(eid);
437 if (!firstAuthKey.equals(authKey)) {
438 LOG.debug("Map register packet contained several eids. Authentication keys for first one and for " +
439 "{} are different.",LispAddressStringifier.getString(eid));
447 private void handleMapNotify(ByteBuffer inBuffer, InetAddress sourceAddress, int port) {
449 MapNotify mapNotify = MapNotifySerializer.getInstance().deserialize(inBuffer);
450 GotMapNotifyBuilder gotMapNotifyBuilder = new GotMapNotifyBuilder();
451 gotMapNotifyBuilder.setMapNotify(LispNotificationHelper.convertMapNotify(mapNotify));
452 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
453 transportAddressBuilder.setIpAddress(LispNotificationHelper
454 .getIpAddressBinaryFromInetAddress(sourceAddress));
455 transportAddressBuilder.setPort(new PortNumber(port));
456 gotMapNotifyBuilder.setTransportAddress(transportAddressBuilder.build());
457 if (notificationPublishService != null) {
458 notificationPublishService.putNotification(gotMapNotifyBuilder.build());
459 LOG.trace("MapNotify was published!");
461 LOG.warn("Notification Provider is null!");
463 } catch (RuntimeException re) {
464 throw new LispMalformedPacketException("Couldn't deserialize Map-Notify (len="
465 + inBuffer.capacity() + ")", re);
466 } catch (InterruptedException e) {
467 LOG.warn("Notification publication interrupted!");
472 private void handleMapReply(ByteBuffer inBuffer, InetAddress sourceAddress, int port) {
474 MapReply mapReply = MapReplySerializer.getInstance().deserialize(inBuffer);
475 GotMapReplyBuilder gotMapReplyBuilder = new GotMapReplyBuilder();
476 gotMapReplyBuilder.setMapReply(LispNotificationHelper.convertMapReply(mapReply));
477 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
478 transportAddressBuilder.setIpAddress(LispNotificationHelper
479 .getIpAddressBinaryFromInetAddress(sourceAddress));
480 transportAddressBuilder.setPort(new PortNumber(port));
481 gotMapReplyBuilder.setTransportAddress(transportAddressBuilder.build());
482 if (notificationPublishService != null) {
483 notificationPublishService.putNotification(gotMapReplyBuilder.build());
484 LOG.trace("MapReply was published!");
486 LOG.warn("Notification Provider is null!");
488 } catch (RuntimeException re) {
489 throw new LispMalformedPacketException("Couldn't deserialize Map-Reply (len="
490 + inBuffer.capacity() + ")", re);
491 } catch (InterruptedException e) {
492 LOG.warn("Notification publication interrupted!");
496 private void handleStats(int type) {
497 if (lispSbStats != null) {
498 if (type <= LispSouthboundStats.MAX_LISP_TYPES) {
499 lispSbStats.incrementRx(type);
501 lispSbStats.incrementRxUnknown();
507 protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
508 if (isReadFromChannelEnabled) {
509 if (LOG.isTraceEnabled()) {
510 LOG.trace("Received UDP packet from {}:{} with content:\n{}", msg.sender().getHostString(),
511 msg.sender().getPort(), ByteBufUtil.prettyHexDump(msg.content()));
518 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
523 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
524 LOG.error("Error on channel: " + cause, cause);
528 public void close() throws Exception {
529 authenticationKeyDataListener.closeDataChangeListener();
532 public void setSimpleMapCache(final SimpleMapCache smc) {
536 public void setDataBroker(final DataBroker dataBroker) {
537 this.dataBroker = dataBroker;
540 public void setNotificationProvider(NotificationPublishService nps) {
541 this.notificationPublishService = nps;
544 public void setMapRegisterCache(final MapRegisterCache mapRegisterCache) {
545 this.mapRegisterCache = mapRegisterCache;
548 public void setMapRegisterCacheEnabled(final boolean mapRegisterCacheEnabled) {
549 this.mapRegisterCacheEnabled = mapRegisterCacheEnabled;
553 * Restore all keys from MDSAL datastore
555 public void restoreDaoFromDatastore() {
556 final List<AuthenticationKey> authKeys = dsbe.getAllAuthenticationKeys();
557 LOG.info("Restoring {} keys from datastore into southbound DAO", authKeys.size());
559 for (AuthenticationKey authKey : authKeys) {
560 final Eid key = authKey.getEid();
561 final MappingAuthkey mappingAuthkey = authKey.getMappingAuthkey();
562 LOG.debug("Adding authentication key '{}' with key-ID {} for {}", mappingAuthkey.getKeyString(),
563 mappingAuthkey.getKeyType(),
564 LispAddressStringifier.getString(key));
565 smc.addAuthenticationKey(key, mappingAuthkey);
570 Preconditions.checkNotNull(dataBroker);
571 Preconditions.checkNotNull(smc);
572 this.authenticationKeyDataListener = new AuthenticationKeyDataListener(dataBroker, smc);
573 dsbe = new DataStoreBackEnd(dataBroker);
576 public void setIsReadFromChannelEnabled(boolean isReadFromChannelEnabled) {
577 this.isReadFromChannelEnabled = isReadFromChannelEnabled;