24f637d343462bb8df8403afc043ad5e86a694d3
[lispflowmapping.git] / mappingservice / southbound / src / main / java / org / opendaylight / lispflowmapping / southbound / lisp / LispSouthboundService.java
1 /*
2  * Copyright (c) 2013 Contextream, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.lispflowmapping.southbound.lisp;
10
11 import java.net.DatagramPacket;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.nio.ByteBuffer;
15
16 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
17 import org.opendaylight.lispflowmapping.implementation.serializer.LispMessage;
18 import org.opendaylight.lispflowmapping.implementation.serializer.LispMessageEnum;
19 import org.opendaylight.lispflowmapping.implementation.serializer.MapRegisterSerializer;
20 import org.opendaylight.lispflowmapping.implementation.serializer.MapRequestSerializer;
21 import org.opendaylight.lispflowmapping.implementation.util.ByteUtil;
22 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
23 import org.opendaylight.lispflowmapping.southbound.lisp.network.PacketHeader;
24 import org.opendaylight.lispflowmapping.type.sbplugin.MapRegisterNotification;
25 import org.opendaylight.lispflowmapping.type.sbplugin.MapRequestNotification;
26 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.LispAFIAddress;
27 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.LispIpv4Address;
28 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.LispIpv6Address;
29 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRegister;
30 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest;
31 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.Address;
32 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.maprequest.ItrRloc;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 public class LispSouthboundService implements ILispSouthboundService {
37     private NotificationProviderService notificationProvider;
38     protected static final Logger logger = LoggerFactory.getLogger(LispSouthboundService.class);
39
40     public void setNotificationProvider(NotificationProviderService nps) {
41         this.notificationProvider = nps;
42     }
43
44     public void handlePacket(DatagramPacket packet) {
45         ByteBuffer inBuffer = ByteBuffer.wrap(packet.getData(), 0, packet.getLength());
46         Object lispType = LispMessageEnum.valueOf((byte) (ByteUtil.getUnsignedByte(inBuffer, LispMessage.Pos.TYPE) >> 4));
47         if (lispType == LispMessageEnum.EncapsulatedControlMessage) {
48             logger.debug("Recieved packet of type EncapsulatedControlMessage");
49             handleEncapsulatedControlMessage(inBuffer, packet.getAddress());
50         } else if (lispType == LispMessageEnum.MapRequest) {
51             logger.debug("Recieved packet of type MapRequest");
52             handleMapRequest(inBuffer);
53         } else if (lispType == LispMessageEnum.MapRegister) {
54             logger.debug("Recieved packet of type MapRegister");
55             handleMapRegister(inBuffer, packet.getAddress());
56         }
57         logger.debug("Recieved unknown packet type");
58     }
59
60     private void handleEncapsulatedControlMessage(ByteBuffer inBuffer, InetAddress sourceAddress) {
61         try {
62             extractEncapsulatedSourcePort(inBuffer);
63             handleMapRequest(inBuffer);
64         } catch (RuntimeException re) {
65             throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re);
66         }
67     }
68
69     private void handleMapRequest(ByteBuffer inBuffer) {
70         try {
71             MapRequest request = MapRequestSerializer.getInstance().deserialize(inBuffer);
72             InetAddress finalSourceAddress = null;
73             for (ItrRloc itr : request.getItrRloc()) {
74                 Address addr = itr.getLispAddressContainer().getAddress();
75                 if (addr instanceof LispIpv4Address) {
76                     try {
77                         finalSourceAddress = InetAddress.getByName(((LispIpv4Address) addr).getIpv4Address().getValue());
78                     } catch (UnknownHostException e) {
79                     }
80                     break;
81                 }
82                 if (addr instanceof LispIpv6Address) {
83                     try {
84                         finalSourceAddress = InetAddress.getByName((((LispIpv6Address) addr).getIpv6Address().getValue()));
85                     } catch (UnknownHostException e) {
86                     }
87                     break;
88                 }
89             }
90             if (finalSourceAddress == null) {
91                 throw new LispMalformedPacketException("Couldn't deserialize Map-Request, no ITR Rloc found!");
92             }
93
94             MapRequestNotification requestNotification = new MapRequestNotification(request, finalSourceAddress);
95             if (notificationProvider != null) {
96                 notificationProvider.publish(requestNotification);
97                 logger.debug("MapRequest was published!");
98             } else {
99                 logger.error("Notification Provider is null!");
100             }
101         } catch (RuntimeException re) {
102             throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re);
103         }
104     }
105
106     private int extractEncapsulatedSourcePort(ByteBuffer inBuffer) {
107         try {
108             inBuffer.position(PacketHeader.Length.LISP_ENCAPSULATION);
109             int ipType = (inBuffer.get() >> 4);
110             if (ipType == 4) {
111                 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV4 - 1);
112             } else {
113                 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV6_NO_EXT - 1);
114             }
115
116             int encapsulatedSourcePort = inBuffer.getShort() & 0xFFFF;
117             inBuffer.position(inBuffer.position() + PacketHeader.Length.UDP - 2);
118             return encapsulatedSourcePort;
119         } catch (RuntimeException re) {
120             throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re);
121         }
122     }
123
124     private void handleMapRegister(ByteBuffer inBuffer, InetAddress sourceAddress) {
125         try {
126             MapRegister mapRegister = MapRegisterSerializer.getInstance().deserialize(inBuffer);
127             MapRegisterNotification registerNotification = new MapRegisterNotification(mapRegister, sourceAddress);
128             if (notificationProvider != null) {
129                 notificationProvider.publish(registerNotification);
130                 logger.debug("MapRegister was published!");
131             } else {
132                 logger.error("Notification Provider is null!");
133             }
134         } catch (RuntimeException re) {
135             throw new LispMalformedPacketException("Couldn't deserialize Map-Register (len=" + inBuffer.capacity() + ")", re);
136         }
137     }
138 }