1
2
3
4
5
6
7
8
9 package org.opendaylight.lispflowmapping.southbound.lisp;
10
11 import io.netty.buffer.ByteBufUtil;
12 import io.netty.channel.ChannelHandlerContext;
13 import io.netty.channel.SimpleChannelInboundHandler;
14 import io.netty.channel.socket.DatagramPacket;
15
16 import java.net.InetAddress;
17 import java.nio.ByteBuffer;
18
19 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
20 import org.opendaylight.lispflowmapping.southbound.util.LispNotificationHelper;
21 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
22 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
23 import org.opendaylight.lispflowmapping.lisp.util.MapRequestUtil;
24 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
25 import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer;
26 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrReplyMappingBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrRequestMappingBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.transport.address.TransportAddressBuilder;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 public class LispXtrSouthboundHandler extends SimpleChannelInboundHandler<DatagramPacket> implements ILispSouthboundService {
38 private NotificationPublishService notificationPublishService;
39 protected static final Logger LOG = LoggerFactory.getLogger(LispXtrSouthboundHandler.class);
40
41 public void setNotificationProvider(NotificationPublishService nps) {
42 this.notificationPublishService = nps;
43 }
44
45 public void handlePacket(DatagramPacket packet) {
46 ByteBuffer inBuffer = packet.content().nioBuffer();
47 Object lispType = MessageType.forValue((int) (ByteUtil.getUnsignedByte(inBuffer, LispMessage.Pos.TYPE) >> 4));
48 if (lispType == MessageType.MapRequest) {
49 LOG.trace("Received packet of type MapRequest for xTR");
50 handleMapRequest(inBuffer);
51 } else if (lispType == MessageType.MapReply){
52 LOG.trace("Received packet of type MapReply for xTR");
53 handleMapReply(inBuffer);
54 } else {
55 LOG.warn("Received unknown packet type");
56 }
57 }
58
59 private void handleMapRequest(ByteBuffer inBuffer) {
60 try {
61 MapRequest request = MapRequestSerializer.getInstance().deserialize(inBuffer);
62 InetAddress finalSourceAddress = MapRequestUtil.selectItrRloc(request);
63 if (finalSourceAddress == null) {
64 throw new LispMalformedPacketException("Couldn't deserialize Map-Request, no ITR Rloc found!");
65 }
66
67 XtrRequestMappingBuilder requestMappingBuilder = new XtrRequestMappingBuilder();
68 requestMappingBuilder.setMapRequest(LispNotificationHelper.convertMapRequest(request));
69 TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder();
70 transportAddressBuilder.setIpAddress(LispNotificationHelper.getIpAddressFromInetAddress(finalSourceAddress));
71 transportAddressBuilder.setPort(new PortNumber(LispMessage.PORT_NUM));
72 requestMappingBuilder.setTransportAddress(transportAddressBuilder.build());
73 if (notificationPublishService != null) {
74 notificationPublishService.putNotification(requestMappingBuilder.build());
75 LOG.trace("MapRequest was published!");
76 } else {
77 LOG.warn("Notification Provider is null!");
78 }
79 } catch (RuntimeException re) {
80 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re);
81 } catch (InterruptedException e) {
82 LOG.warn("Notification publication interrupted!");
83 }
84 }
85
86 private void handleMapReply(ByteBuffer buffer) {
87 try {
88 MapReply reply = MapReplySerializer.getInstance().deserialize(buffer);
89
90 XtrReplyMappingBuilder replyMappingBuilder = new XtrReplyMappingBuilder();
91 replyMappingBuilder.setMapReply(LispNotificationHelper.convertMapReply(reply));
92
93 if (notificationPublishService != null) {
94 notificationPublishService.putNotification(replyMappingBuilder.build());
95 LOG.trace("MapReply was published!");
96 } else {
97 LOG.warn("Notification Provider is null!");
98 }
99 } catch (RuntimeException re) {
100 throw new LispMalformedPacketException("Couldn't deserialize Map-Reply (len=" + buffer.capacity() + ")", re);
101 } catch (InterruptedException e) {
102 LOG.warn("Notification publication interrupted!");
103 }
104 }
105
106 @Override
107 protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
108 if (LOG.isTraceEnabled()) {
109 LOG.trace("Received UDP packet from {}:{} with content:\n{}", msg.sender().getHostString(),
110 msg.sender().getPort(), ByteBufUtil.prettyHexDump(msg.content()));
111 }
112 handlePacket(msg);
113 }
114
115 @Override
116 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
117 ctx.flush();
118 }
119
120 @Override
121 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
122 LOG.error("Error on channel: " + cause, cause);
123 }
124 }