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 io.netty.buffer.ByteBufUtil;
12 import io.netty.channel.Channel;
13 import io.netty.channel.ChannelHandler;
14 import io.netty.channel.ChannelHandlerContext;
15 import io.netty.channel.SimpleChannelInboundHandler;
16 import io.netty.channel.socket.DatagramPacket;
17 import java.net.InetAddress;
18 import java.nio.ByteBuffer;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
23 import java.util.Objects;
24 import org.opendaylight.lispflowmapping.config.ConfigIni;
25 import org.opendaylight.lispflowmapping.lisp.authentication.ILispAuthentication;
26 import org.opendaylight.lispflowmapping.lisp.authentication.LispAuthenticationUtil;
27 import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
28 import org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer;
29 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
30 import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer;
31 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
32 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
33 import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
34 import org.opendaylight.lispflowmapping.lisp.util.MapRequestUtil;
35 import org.opendaylight.lispflowmapping.southbound.ConcurrentLispSouthboundStats;
36 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
37 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterPartialDeserializer;
38 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
39 import org.opendaylight.lispflowmapping.southbound.lisp.network.PacketHeader;
40 import org.opendaylight.lispflowmapping.southbound.util.LispNotificationHelper;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMappingBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapNotifyBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapReplyBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAlive;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAliveBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMappingBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadata;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddress;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddressBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValue;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValueBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.transport.address.TransportAddressBuilder;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
68 @ChannelHandler.Sharable
69 public class LispSouthboundHandler extends SimpleChannelInboundHandler<DatagramPacket>
70 implements ILispSouthboundService, AutoCloseable {
71 protected static final Logger LOG = LoggerFactory.getLogger(LispSouthboundHandler.class);
73 //TODO: think whether this field can be accessed through mappingservice or some other configuration parameter
74 private boolean authenticationEnabled = ConfigIni.getInstance().isAuthEnabled();
75 private final LispSouthboundPlugin lispSbPlugin;
76 private boolean isReadFromChannelEnabled = true;
78 private Channel channel;
80 public LispSouthboundHandler(LispSouthboundPlugin lispSbPlugin) {
81 this.lispSbPlugin = lispSbPlugin;
84 public void handlePacket(DatagramPacket msg) {
85 ByteBuffer inBuffer = msg.content().nioBuffer();
86 int type = ByteUtil.getUnsignedByte(inBuffer, LispMessage.Pos.TYPE) >> 4;
88 Object lispType = MessageType.forValue(type);
89 if (lispType == MessageType.EncapsulatedControlMessage) {
90 LOG.trace("Received packet of type Encapsulated Control Message");
91 handleEncapsulatedControlMessage(inBuffer, msg.sender().getAddress());
92 } else if (lispType == MessageType.MapRequest) {
93 LOG.trace("Received packet of type Map-Request");
94 handleMapRequest(inBuffer, msg.sender().getAddress(), msg.sender().getPort());
95 } else if (lispType == MessageType.MapRegister) {
96 LOG.trace("Received packet of type Map-Register");
97 handleMapRegister(inBuffer, msg.sender().getAddress(), msg.sender().getPort());
98 } else if (lispType == MessageType.MapNotify) {
99 LOG.trace("Received packet of type Map-Notify");
100 handleMapNotify(inBuffer, msg.sender().getAddress(), msg.sender().getPort());
101 } else if (lispType == MessageType.MapReply) {
102 LOG.trace("Received packet of type Map-Reply");
103 handleMapReply(inBuffer, msg.sender().getAddress(), msg.sender().getPort());
105 LOG.warn("Received unknown LISP control packet (type " + ((lispType != null) ? lispType : type) + ")");
109 @SuppressWarnings("checkstyle:IllegalCatch")
110 private void handleEncapsulatedControlMessage(ByteBuffer inBuffer, InetAddress sourceAddress) {
112 handleMapRequest(inBuffer, sourceAddress, extractEncapsulatedSourcePort(inBuffer));
113 } catch (RuntimeException re) {
114 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len="
115 + inBuffer.capacity() + ")", re);
119 @SuppressWarnings("checkstyle:IllegalCatch")
120 private void handleMapRequest(ByteBuffer inBuffer, InetAddress sourceAddress, int port) {
122 MapRequest request = MapRequestSerializer.getInstance().deserialize(inBuffer, sourceAddress);
123 InetAddress finalSourceAddress = MapRequestUtil.selectItrRloc(request);
124 if (finalSourceAddress == null) {
125 throw new LispMalformedPacketException("Couldn't deserialize Map-Request, no ITR Rloc found!");
128 RequestMappingBuilder requestMappingBuilder = new RequestMappingBuilder();
129 requestMappingBuilder.setMapRequest(LispNotificationHelper.convertMapRequest(request));
130 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
131 transportAddressBuilder.setIpAddress(
132 LispNotificationHelper.getIpAddressBinaryFromInetAddress(finalSourceAddress));
133 transportAddressBuilder.setPort(new PortNumber(port));
134 requestMappingBuilder.setTransportAddress(transportAddressBuilder.build());
135 lispSbPlugin.sendNotificationIfPossible(requestMappingBuilder.build());
136 } catch (RuntimeException re) {
137 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len="
138 + inBuffer.capacity() + ")", re);
139 } catch (InterruptedException e) {
140 LOG.warn("Notification publication interrupted!");
144 @SuppressWarnings("checkstyle:IllegalCatch")
145 private int extractEncapsulatedSourcePort(ByteBuffer inBuffer) {
147 inBuffer.position(PacketHeader.Length.LISP_ENCAPSULATION);
148 int ipType = (inBuffer.get() >> 4);
150 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV4 - 1);
151 } else if (ipType == 6) {
152 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV6_NO_EXT - 1);
154 throw new LispMalformedPacketException(
155 "Couldn't deserialize Map-Request: inner packet has unknown IP version: " + ipType);
158 int encapsulatedSourcePort = inBuffer.getShort() & 0xFFFF;
159 inBuffer.position(inBuffer.position() + PacketHeader.Length.UDP - 2);
160 return encapsulatedSourcePort;
161 } catch (RuntimeException re) {
162 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len="
163 + inBuffer.capacity() + ")", re);
167 @SuppressWarnings("checkstyle:IllegalCatch")
168 private void handleMapRegister(ByteBuffer inBuffer, InetAddress sourceAddress, int port) {
170 Map.Entry<MapRegisterCacheKey, byte[]> artificialEntry = null;
171 MapRegisterCacheKey cacheKey = null;
172 MapRegisterCacheValue cacheValue = null;
173 if (lispSbPlugin.isMapRegisterCacheEnabled()) {
174 artificialEntry = MapRegisterPartialDeserializer.deserializePartially(inBuffer, sourceAddress);
175 cacheKey = artificialEntry == null ? null : artificialEntry.getKey();
176 cacheValue = resolveCacheValue(artificialEntry);
178 if (cacheValue != null) {
179 lispSbPlugin.getStats().incrementCacheHits();
180 MapRegisterCacheMetadata mapRegisterMeta = cacheValue.getMapRegisterCacheMetadata();
181 LOG.debug("Map register message site-ID: {} xTR-ID: {} from cache.", mapRegisterMeta.getSiteId(),
182 mapRegisterMeta.getXtrId());
183 cacheValue = refreshEntry(cacheKey);
184 if (cacheValue != null) {
185 lispSbPlugin.sendNotificationIfPossible(createMappingKeepAlive(cacheValue));
186 if (cacheValue.getMapRegisterCacheMetadata().isWantMapNotify()) {
187 sendMapNotifyMsg(inBuffer, sourceAddress, port, cacheValue);
191 lispSbPlugin.getStats().incrementCacheMisses();
192 MapRegister mapRegister = MapRegisterSerializer.getInstance().deserialize(inBuffer, sourceAddress);
194 MappingAuthkey mappingAuthkey = null;
195 if (authenticationEnabled) {
196 mappingAuthkey = tryToAuthenticateMessage(mapRegister, inBuffer);
197 if (mappingAuthkey == null) {
202 AddMappingBuilder addMappingBuilder = new AddMappingBuilder();
203 addMappingBuilder.setMapRegister(LispNotificationHelper.convertMapRegister(mapRegister));
204 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
205 transportAddressBuilder.setIpAddress(LispNotificationHelper.getIpAddressBinaryFromInetAddress(
207 transportAddressBuilder.setPort(new PortNumber(port));
208 addMappingBuilder.setTransportAddress(transportAddressBuilder.build());
209 lispSbPlugin.sendNotificationIfPossible(addMappingBuilder.build());
210 if (artificialEntry != null) {
211 final MapRegisterCacheMetadataBuilder cacheMetadataBldNew = new
212 MapRegisterCacheMetadataBuilder();
213 cacheMetadataBldNew.setEidLispAddress(provideEidPrefixesFromMessage(mapRegister));
214 cacheMetadataBldNew.setXtrId(mapRegister.getXtrId());
215 cacheMetadataBldNew.setSiteId(mapRegister.getSiteId());
216 cacheMetadataBldNew.setWantMapNotify(mapRegister.isWantMapNotify());
217 cacheMetadataBldNew.setMergeEnabled(mapRegister.isMergeEnabled());
218 cacheMetadataBldNew.setTimestamp(System.currentTimeMillis());
220 final MapRegisterCacheValueBuilder cacheValueBldNew = new MapRegisterCacheValueBuilder();
221 cacheValueBldNew.setPacketData(artificialEntry.getValue());
222 cacheValueBldNew.setMappingAuthkey(mappingAuthkey);
223 cacheValueBldNew.setMapRegisterCacheMetadata(cacheMetadataBldNew.build());
225 lispSbPlugin.getMapRegisterCache().addEntry(cacheKey, cacheValueBldNew.build());
228 } catch (RuntimeException re) {
229 throw new LispMalformedPacketException("Couldn't deserialize Map-Register (len="
230 + inBuffer.capacity() + ")", re);
231 } catch (InterruptedException e) {
232 LOG.warn("Notification publication interrupted!");
236 private MapRegisterCacheValue refreshEntry(final MapRegisterCacheKey cacheKey) {
237 MapRegisterCacheValue mapRegisterCacheValue = lispSbPlugin.getMapRegisterCache().refreshEntry(cacheKey);
238 if (mapRegisterCacheValue != null) {
239 mapRegisterCacheValue = refreshAuthKeyIfNecessary(mapRegisterCacheValue);
240 lispSbPlugin.getMapRegisterCache().addEntry(cacheKey, mapRegisterCacheValue);
241 return mapRegisterCacheValue;
246 private MapRegisterCacheValue refreshAuthKeyIfNecessary(MapRegisterCacheValue mapRegisterCacheValue) {
247 final List<EidLispAddress> eids = mapRegisterCacheValue.getMapRegisterCacheMetadata().getEidLispAddress();
249 if (lispSbPlugin.getAuthenticationKeyDataListener().authKeysForEidsUnchanged(
250 eids, lispSbPlugin.getMapRegisterCacheTimeout())) {
251 return mapRegisterCacheValue;
254 final MappingAuthkey mappingAuthkey = provideAuthenticateKey(eids);
255 final MapRegisterCacheValueBuilder newMapRegisterCacheValueBuilder = new MapRegisterCacheValueBuilder(
256 mapRegisterCacheValue);
257 final MapRegisterCacheMetadataBuilder newMapRegisterCacheMetadataBuilder =
258 new MapRegisterCacheMetadataBuilder(mapRegisterCacheValue.getMapRegisterCacheMetadata());
260 newMapRegisterCacheValueBuilder.setMappingAuthkey(mappingAuthkey);
261 newMapRegisterCacheValueBuilder.setMapRegisterCacheMetadata(newMapRegisterCacheMetadataBuilder.build());
262 return newMapRegisterCacheValueBuilder.build();
265 private MapRegisterCacheValue resolveCacheValue(Map.Entry<MapRegisterCacheKey, byte[]> entry) {
267 final MapRegisterCacheValue mapRegisterCacheValue =
268 lispSbPlugin.getMapRegisterCache().getEntry(entry.getKey());
269 if (mapRegisterCacheValue != null) {
270 final long creationTime = mapRegisterCacheValue.getMapRegisterCacheMetadata().getTimestamp();
271 final long currentTime = System.currentTimeMillis();
272 if (currentTime - creationTime > lispSbPlugin.getMapRegisterCacheTimeout()) {
273 lispSbPlugin.getMapRegisterCache().removeEntry(entry.getKey());
275 } else if (Arrays.equals(mapRegisterCacheValue.getPacketData(), entry.getValue())) {
276 return mapRegisterCacheValue;
283 private MappingKeepAlive createMappingKeepAlive(final MapRegisterCacheValue value) {
284 MappingKeepAliveBuilder mappingKeepAliveBuilder = new MappingKeepAliveBuilder();
285 mappingKeepAliveBuilder.setMapRegisterCacheMetadata(value.getMapRegisterCacheMetadata());
286 return mappingKeepAliveBuilder.build();
290 * Returns null if not all of eids have the same value of authentication key.
292 private MappingAuthkey provideAuthenticateKey(final List<EidLispAddress> eidLispAddresses) {
293 MappingAuthkey firstAuthKey = null;
294 for (int i = 0; i < eidLispAddresses.size(); i++) {
295 final Eid eid = eidLispAddresses.get(i).getEid();
297 firstAuthKey = lispSbPlugin.getAkdb().getAuthenticationKey(eid);
299 final MappingAuthkey authKey = lispSbPlugin.getAkdb().getAuthenticationKey(eid);
300 if (!Objects.equals(firstAuthKey, authKey)) {
309 private void sendMapNotifyMsg(final ByteBuffer inBuffer, final InetAddress inetAddress, int portNumber,
310 MapRegisterCacheValue mapRegisterValue) {
311 if (mapRegisterValue.getMappingAuthkey().getKeyType() != null) {
312 ByteBuffer outBuffer = transformMapRegisterToMapNotify(inBuffer);
313 if (mapRegisterValue.getMappingAuthkey().getKeyType() != 0) {
314 outBuffer = calculateAndSetNewMAC(outBuffer, mapRegisterValue.getMappingAuthkey().getKeyString());
316 outBuffer.position(0);
317 lispSbPlugin.handleSerializedLispBuffer(inetAddress, outBuffer, MessageType.MapNotify, portNumber,
320 LOG.error("Map-Register Cache: authentication succeeded, but can't find auth key for sending Map-Notify");
325 * Calculates new message authentication code (MAC) for notify message.
327 private ByteBuffer calculateAndSetNewMAC(final ByteBuffer buffer, final String authKey) {
328 final byte[] authenticationData = LispAuthenticationUtil.createAuthenticationData(buffer, authKey);
329 buffer.position(ILispAuthentication.MAP_REGISTER_AND_NOTIFY_AUTHENTICATION_POSITION);
330 buffer.put(authenticationData);
334 private ByteBuffer transformMapRegisterToMapNotify(final ByteBuffer buffer) {
336 byte typeAndFlags = buffer.get(0);
337 // Shift the xTR-ID present and built for an RTR bits to their correct position
338 byte flags = (byte) ((typeAndFlags << 2) & 0x0F);
339 // Set control message type to 4 (Map-Notify)
341 // Combine the nibbles
342 typeAndFlags = (byte) (type | flags);
343 byte[] byteReplacement = new byte[] {typeAndFlags, 0x00, 0x00};
344 buffer.put(byteReplacement);
349 private List<EidLispAddress> provideEidPrefixesFromMessage(final MapRegister mapRegister) {
350 List<EidLispAddress> eidsResult = new ArrayList<>();
351 for (MappingRecordItem mappingRecordItem : mapRegister.getMappingRecordItem()) {
352 final EidLispAddressBuilder eidLispAddressBuilder = new EidLispAddressBuilder();
353 final Eid eid = mappingRecordItem.getMappingRecord().getEid();
354 eidLispAddressBuilder.setEidLispAddressId(LispAddressStringifier.getString(eid));
355 eidLispAddressBuilder.setEid(eid);
356 eidsResult.add(eidLispAddressBuilder.build());
362 * Checks whether authentication data is valid.
364 * <p>Methods pass through all records from map register message. For the EID of the first record it gets
365 * authentication key and does validation of authentication data again this authentication key. If it pass
366 * it just checks for remaining records (and its EID) whether they have the same authentication key stored in
367 * the authentication key database.
369 * @return Returns authentication key if all of EIDs have the same authentication key or null otherwise
371 private MappingAuthkey tryToAuthenticateMessage(final MapRegister mapRegister, final ByteBuffer byteBuffer) {
372 if (lispSbPlugin.getAkdb() == null) {
373 LOG.debug("Simple map cache wasn't instantieted and set.");
377 MappingAuthkey firstAuthKey = null;
378 final List<MappingRecordItem> mappingRecords = mapRegister.getMappingRecordItem();
379 for (int i = 0; i < mappingRecords.size(); i++) {
380 final MappingRecordItem recordItem = mappingRecords.get(i);
381 final MappingRecord mappingRecord = recordItem.getMappingRecord();
383 firstAuthKey = lispSbPlugin.getAkdb().getAuthenticationKey(mappingRecord.getEid());
384 if (!LispAuthenticationUtil.validate(mapRegister, byteBuffer, mappingRecord.getEid(), firstAuthKey)) {
388 final Eid eid = mappingRecord.getEid();
389 final MappingAuthkey authKey = lispSbPlugin.getAkdb().getAuthenticationKey(eid);
390 if (!firstAuthKey.equals(authKey)) {
391 LOG.debug("Map register packet contained several eids. Authentication keys for first one and for "
392 + "{} are different.",LispAddressStringifier.getString(eid));
400 @SuppressWarnings("checkstyle:IllegalCatch")
401 private void handleMapNotify(ByteBuffer inBuffer, InetAddress sourceAddress, int port) {
403 MapNotify mapNotify = MapNotifySerializer.getInstance().deserialize(inBuffer);
404 GotMapNotifyBuilder gotMapNotifyBuilder = new GotMapNotifyBuilder();
405 gotMapNotifyBuilder.setMapNotify(LispNotificationHelper.convertMapNotify(mapNotify));
406 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
407 transportAddressBuilder.setIpAddress(LispNotificationHelper
408 .getIpAddressBinaryFromInetAddress(sourceAddress));
409 transportAddressBuilder.setPort(new PortNumber(port));
410 gotMapNotifyBuilder.setTransportAddress(transportAddressBuilder.build());
411 lispSbPlugin.sendNotificationIfPossible(gotMapNotifyBuilder.build());
412 } catch (RuntimeException re) {
413 throw new LispMalformedPacketException("Couldn't deserialize Map-Notify (len="
414 + inBuffer.capacity() + ")", re);
415 } catch (InterruptedException e) {
416 LOG.warn("Notification publication interrupted!");
420 @SuppressWarnings("checkstyle:IllegalCatch")
421 private void handleMapReply(ByteBuffer inBuffer, InetAddress sourceAddress, int port) {
423 MapReply mapReply = MapReplySerializer.getInstance().deserialize(inBuffer);
424 GotMapReplyBuilder gotMapReplyBuilder = new GotMapReplyBuilder();
425 gotMapReplyBuilder.setMapReply(LispNotificationHelper.convertMapReply(mapReply));
426 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
427 transportAddressBuilder.setIpAddress(LispNotificationHelper
428 .getIpAddressBinaryFromInetAddress(sourceAddress));
429 transportAddressBuilder.setPort(new PortNumber(port));
430 gotMapReplyBuilder.setTransportAddress(transportAddressBuilder.build());
431 lispSbPlugin.sendNotificationIfPossible(gotMapReplyBuilder.build());
432 } catch (RuntimeException re) {
433 throw new LispMalformedPacketException("Couldn't deserialize Map-Reply (len="
434 + inBuffer.capacity() + ")", re);
435 } catch (InterruptedException e) {
436 LOG.warn("Notification publication interrupted!");
440 private void handleStats(int type) {
441 if (lispSbPlugin.getStats() != null) {
442 if (type <= ConcurrentLispSouthboundStats.MAX_LISP_TYPES) {
443 lispSbPlugin.getStats().incrementRx(type);
445 lispSbPlugin.getStats().incrementRxUnknown();
451 protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
452 if (isReadFromChannelEnabled) {
453 if (LOG.isTraceEnabled()) {
454 LOG.trace("Received UDP packet from {}:{} with content:\n{}", msg.sender().getHostString(),
455 msg.sender().getPort(), ByteBufUtil.prettyHexDump(msg.content()));
457 this.channel = ctx.channel();
463 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
468 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
469 LOG.error("Error on channel: " + cause, cause);
473 public void close() throws Exception {