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