2 * Copyright (c) 2013 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 java.net.DatagramPacket;
12 import java.nio.ByteBuffer;
14 import org.opendaylight.lispflowmapping.implementation.serializer.LispMessage;
15 import org.opendaylight.lispflowmapping.implementation.serializer.LispMessageEnum;
16 import org.opendaylight.lispflowmapping.implementation.serializer.MapNotifySerializer;
17 import org.opendaylight.lispflowmapping.implementation.serializer.MapRegisterSerializer;
18 import org.opendaylight.lispflowmapping.implementation.serializer.MapReplySerializer;
19 import org.opendaylight.lispflowmapping.implementation.serializer.MapRequestSerializer;
20 import org.opendaylight.lispflowmapping.implementation.util.ByteUtil;
21 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolver;
22 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServer;
23 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
24 import org.opendaylight.lispflowmapping.southbound.lisp.network.PacketHeader;
25 import org.opendaylight.lispflowmapping.type.lisp.MapNotify;
26 import org.opendaylight.lispflowmapping.type.lisp.MapRegister;
27 import org.opendaylight.lispflowmapping.type.lisp.MapReply;
28 import org.opendaylight.lispflowmapping.type.lisp.MapRequest;
29 import org.opendaylight.lispflowmapping.type.lisp.address.LispAddress;
30 import org.opendaylight.lispflowmapping.type.lisp.address.LispIPAddress;
32 public class LispSouthboundService implements ILispSouthboundService {
33 private IMapResolver mapResolver;
34 private IMapServer mapServer;
36 public LispSouthboundService(IMapResolver mapResolver, IMapServer mapServer) {
37 this.mapResolver = mapResolver;
38 this.mapServer = mapServer;
41 public DatagramPacket handlePacket(DatagramPacket packet) {
42 ByteBuffer inBuffer = ByteBuffer.wrap(packet.getData(), 0, packet.getLength());
43 Object lispType = LispMessageEnum.valueOf((byte) (ByteUtil.getUnsignedByte(inBuffer, LispMessage.Pos.TYPE) >> 4));
44 if (lispType == LispMessageEnum.EncapsulatedControlMessage) {
45 return handleEncapsulatedControlMessage(inBuffer);
46 } else if (lispType == LispMessageEnum.MapRequest) {
47 return handleMapRequest(inBuffer, true);
48 } else if (lispType == LispMessageEnum.MapRegister) {
49 return handleMapRegister(inBuffer);
54 private DatagramPacket handleEncapsulatedControlMessage(ByteBuffer inBuffer) {
56 int encapsulatedSourcePort = extractEncapsulatedSourcePort(inBuffer);
57 DatagramPacket replyPacket = handleMapRequest(inBuffer, false);
58 replyPacket.setPort(encapsulatedSourcePort);
60 } catch (RuntimeException re) {
61 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re);
65 private DatagramPacket handleMapRequest(ByteBuffer inBuffer, boolean addITRAddress) {
67 MapRequest request = MapRequestSerializer.getInstance().deserialize(inBuffer);
68 MapReply mapReply = mapResolver.handleMapRequest(request);
69 ByteBuffer outBuffer = MapReplySerializer.getInstance().serialize(mapReply);
71 DatagramPacket replyPacket = new DatagramPacket(outBuffer.array(), outBuffer.capacity());
75 replyPacket.setPort(LispMessage.PORT_NUM);
76 for (LispAddress address : request.getItrRlocs()) {
77 if (address instanceof LispIPAddress) {
78 replyPacket.setAddress(((LispIPAddress) address).getAddress());
82 throw new LispMalformedPacketException("No IP address in the ITR's RLOC's");
83 } catch (RuntimeException re) {
84 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re);
88 private int extractEncapsulatedSourcePort(ByteBuffer inBuffer) {
90 inBuffer.position(PacketHeader.Length.LISP_ENCAPSULATION);
91 int ipType = (inBuffer.get() >> 4);
93 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV4 - 1);
95 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV6_NO_EXT - 1);
98 int encapsulatedSourcePort = inBuffer.getShort() & 0xFFFF;
99 inBuffer.position(inBuffer.position() + PacketHeader.Length.UDP - 2);
100 return encapsulatedSourcePort;
101 } catch (RuntimeException re) {
102 throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re);
106 private DatagramPacket handleMapRegister(ByteBuffer inBuffer) {
108 MapRegister mapRegister = MapRegisterSerializer.getInstance().deserialize(inBuffer);
109 MapNotify mapNotify = mapServer.handleMapRegister(mapRegister);
111 if (mapNotify != null) {
112 ByteBuffer outBuffer = MapNotifySerializer.getInstance().serialize(mapNotify);
113 DatagramPacket notify = new DatagramPacket(outBuffer.array(), outBuffer.limit());
114 notify.setPort(LispMessage.PORT_NUM);
119 } catch (RuntimeException re) {
120 throw new LispMalformedPacketException("Couldn't deserialize Map-Register (len=" + inBuffer.capacity() + ")", re);