Merge "check password only if should authenticate" into develop
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / LispMappingService.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.implementation;
10
11 import java.net.InetAddress;
12
13 import org.apache.commons.lang3.tuple.MutablePair;
14 import org.apache.commons.lang3.tuple.Pair;
15 import org.eclipse.osgi.framework.console.CommandInterpreter;
16 import org.eclipse.osgi.framework.console.CommandProvider;
17 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
18 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
19 import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
20 import org.opendaylight.controller.sal.binding.api.NotificationListener;
21 import org.opendaylight.controller.sal.binding.api.NotificationService;
22 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKey;
23 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceNoMaskKey;
24 import org.opendaylight.lispflowmapping.implementation.lisp.MapResolver;
25 import org.opendaylight.lispflowmapping.implementation.lisp.MapServer;
26 import org.opendaylight.lispflowmapping.implementation.util.LispAFIConvertor;
27 import org.opendaylight.lispflowmapping.implementation.util.LispNotificationHelper;
28 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
29 import org.opendaylight.lispflowmapping.interfaces.dao.ILispTypeConverter;
30 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
31 import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
32 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapNotifyHandler;
33 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapRequestResultHandler;
34 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolverAsync;
35 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServerAsync;
36 import org.opendaylight.lispflowmapping.type.sbplugin.ILispSouthboundPlugin;
37 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.AddMapping;
38 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapNotify;
39 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRegister;
40 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapReply;
41 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest;
42 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.RequestMapping;
43 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainer;
44 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainerBuilder;
45 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.Address;
46 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.address.Ipv4Builder;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
49 import org.osgi.framework.BundleContext;
50 import org.osgi.framework.FrameworkUtil;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 public class LispMappingService implements CommandProvider, IFlowMapping, BindingAwareConsumer, //
55         IMapRequestResultHandler, IMapNotifyHandler {
56     protected static final Logger logger = LoggerFactory.getLogger(LispMappingService.class);
57
58     private ILispDAO lispDao = null;
59     private IMapResolverAsync mapResolver;
60     private IMapServerAsync mapServer;
61     private volatile boolean shouldIterateMask;
62     private volatile boolean shouldAuthenticate;
63     private ThreadLocal<MapReply> tlsMapReply = new ThreadLocal<MapReply>();
64     private ThreadLocal<MapNotify> tlsMapNotify = new ThreadLocal<MapNotify>();
65     private ThreadLocal<Pair<MapRequest, InetAddress>> tlsMapRequest = new ThreadLocal<Pair<MapRequest, InetAddress>>();
66
67     private ILispSouthboundPlugin lispSB = null;
68
69     private ConsumerContext session;
70
71     class LispIpv4AddressInMemoryConverter implements ILispTypeConverter<Ipv4Address, Integer> {
72     }
73
74     class LispIpv6AddressInMemoryConverter implements ILispTypeConverter<Ipv6Address, Integer> {
75     }
76
77     class MappingServiceKeyConvertor implements ILispTypeConverter<MappingServiceKey, Integer> {
78     }
79
80     class MappingServiceNoMaskKeyConvertor implements ILispTypeConverter<MappingServiceNoMaskKey, Integer> {
81     }
82
83     void setBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
84         logger.trace("BindingAwareBroker set!");
85         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
86         bindingAwareBroker.registerConsumer(this, bundleContext);
87     }
88
89     void unsetBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
90         logger.debug("BindingAwareBroker was unset in LispMappingService");
91     }
92
93     public void basicInit(ILispDAO dao) {
94         lispDao = dao;
95         mapResolver = new MapResolver(dao);
96         mapServer = new MapServer(dao);
97     }
98
99     void setLispDao(ILispDAO dao) {
100         logger.trace("LispDAO set in LispMappingService");
101         basicInit(dao);
102     }
103
104     void unsetLispDao(ILispDAO dao) {
105         logger.trace("LispDAO was unset in LispMappingService");
106         mapServer = null;
107         mapResolver = null;
108         lispDao = null;
109     }
110
111     public void init() {
112         try {
113             registerWithOSGIConsole();
114             logger.info("LISP (RFC6830) Mapping Service init finished");
115         } catch (Throwable t) {
116             logger.error(t.getStackTrace().toString());
117         }
118     }
119
120     private void registerWithOSGIConsole() {
121         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
122         bundleContext.registerService(CommandProvider.class.getName(), this, null);
123     }
124
125     public void destroy() {
126         logger.info("LISP (RFC6830) Mapping Service is destroyed!");
127         mapResolver = null;
128         mapServer = null;
129     }
130
131     public void _removeEid(final CommandInterpreter ci) {
132         lispDao.remove(LispAFIConvertor.asIPAfiAddress(ci.nextArgument()));
133     }
134
135     public void _dumpAll(final CommandInterpreter ci) {
136         ci.println("EID\tRLOCs");
137         lispDao.getAll(new IRowVisitor() {
138             String lastKey = "";
139
140             public void visitRow(Object keyId, String valueKey, Object value) {
141                 String key = keyId.getClass().getSimpleName() + "#" + keyId;
142                 if (!lastKey.equals(key)) {
143                     ci.println();
144                     ci.print(key + "\t");
145                 }
146                 ci.print(valueKey + "=" + value + "\t");
147                 lastKey = key;
148             }
149         });
150         ci.println();
151         return;
152     }
153
154     public void _setShouldOverwriteRlocs(final CommandInterpreter ci) {
155         try {
156             boolean shouldOverwriteRloc = Boolean.parseBoolean(ci.nextArgument());
157             setOverwrite(shouldOverwriteRloc);
158         } catch (Exception e) {
159             ci.println("Bad Usage!!");
160         }
161
162     }
163
164     public void _addDefaultPassword(final CommandInterpreter ci) {
165         LispAddressContainerBuilder builder = new LispAddressContainerBuilder();
166         builder.setAddress((Address) (new Ipv4Builder().setIpv4Address(new Ipv4Address("0.0.0.0")).build()));
167         addAuthenticationKey(builder.build(), 0, "password");
168     }
169
170     public String getHelp() {
171         StringBuffer help = new StringBuffer();
172         help.append("---LISP Mapping Service---\n");
173         help.append("\t dumpAll        - Dump all current EID -> RLOC mapping\n");
174         help.append("\t removeEid      - Remove a single LispIPv4Address Eid\n");
175         help.append("\t setShouldOverwritingRloc(true/false)      - set the map server's behaivior regarding existing RLOCs\n");
176         return help.toString();
177     }
178
179     public MapReply handleMapRequest(MapRequest request) {
180         tlsMapReply.set(null);
181         tlsMapRequest.set(null);
182         mapResolver.handleMapRequest(request, this);
183         // After this invocation we assume that the thread local is filled with
184         // the reply
185         if (tlsMapRequest.get() != null) {
186             getLispSB().handleMapRequest(tlsMapRequest.get().getLeft(), tlsMapRequest.get().getRight());
187             return null;
188         } else {
189             return tlsMapReply.get();
190         }
191
192     }
193
194     public MapNotify handleMapRegister(MapRegister mapRegister) {
195         tlsMapNotify.set(null);
196         mapServer.handleMapRegister(mapRegister, this);
197         // After this invocation we assume that the thread local is filled with
198         // the reply
199         return tlsMapNotify.get();
200     }
201
202     public String getAuthenticationKey(LispAddressContainer address, int maskLen) {
203         return mapServer.getAuthenticationKey(address, maskLen);
204     }
205
206     public void removeAuthenticationKey(LispAddressContainer address, int maskLen) {
207         mapServer.removeAuthenticationKey(address, maskLen);
208     }
209
210     public void addAuthenticationKey(LispAddressContainer address, int maskLen, String key) {
211         mapServer.addAuthenticationKey(address, maskLen, key);
212     }
213
214     public boolean shouldIterateMask() {
215         return this.shouldIterateMask;
216     }
217
218     public void setShouldIterateMask(boolean shouldIterateMask) {
219         this.shouldIterateMask = shouldIterateMask;
220         this.mapResolver.setShouldIterateMask(shouldIterateMask);
221         this.mapServer.setShouldIterateMask(shouldIterateMask);
222     }
223
224     public void setShouldAuthenticate(boolean shouldAuthenticate) {
225         this.shouldAuthenticate = shouldAuthenticate;
226         this.mapResolver.setShouldAuthenticate(shouldAuthenticate);
227         this.mapServer.setShouldAuthenticate(shouldAuthenticate);
228     }
229
230     public boolean shouldAuthenticate() {
231         return shouldAuthenticate;
232     }
233
234     public void onSessionInitialized(ConsumerContext session) {
235         logger.info("Lisp Consumer session initialized!");
236         NotificationService notificationService = session.getSALService(NotificationService.class);
237         notificationService.registerNotificationListener(AddMapping.class, new MapRegisterNotificationHandler());
238         notificationService.registerNotificationListener(RequestMapping.class, new MapRequestNotificationHandler());
239         this.session = session;
240     }
241
242     private class MapRegisterNotificationHandler implements NotificationListener<AddMapping> {
243
244         @Override
245         public void onNotification(AddMapping mapRegisterNotification) {
246             MapNotify mapNotify = handleMapRegister(mapRegisterNotification.getMapRegister());
247             getLispSB().handleMapNotify(mapNotify,
248                     LispNotificationHelper.getInetAddressFromIpAddress(mapRegisterNotification.getTransportAddress().getIpAddress()));
249
250         }
251     }
252
253     private class MapRequestNotificationHandler implements NotificationListener<RequestMapping> {
254
255         @Override
256         public void onNotification(RequestMapping mapRequestNotification) {
257             MapReply mapReply = handleMapRequest(mapRequestNotification.getMapRequest());
258             getLispSB().handleMapReply(mapReply,
259                     LispNotificationHelper.getInetAddressFromIpAddress(mapRequestNotification.getTransportAddress().getIpAddress()));
260         }
261
262     }
263
264     private ILispSouthboundPlugin getLispSB() {
265         if (lispSB == null) {
266             lispSB = session.getRpcService(ILispSouthboundPlugin.class);
267         }
268         return lispSB;
269     }
270
271     public void handleMapReply(MapReply reply) {
272         tlsMapReply.set(reply);
273     }
274
275     public void handleMapNotify(MapNotify notify) {
276         tlsMapNotify.set(notify);
277     }
278
279     @Override
280     public void handleNonProxyMapRequest(MapRequest mapRequest, InetAddress targetAddress) {
281         tlsMapRequest.set(new MutablePair<MapRequest, InetAddress>(mapRequest, targetAddress));
282     }
283
284     @Override
285     public void clean() {
286         lispDao.removeAll();
287     }
288
289     @Override
290     public boolean shouldOverwrite() {
291         return mapServer.shouldOverwrite();
292     }
293
294     @Override
295     public void setOverwrite(boolean overwrite) {
296         mapServer.setOverwrite(overwrite);
297     }
298
299 }