2 * Copyright (c) 2014 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.implementation;
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
14 import org.eclipse.osgi.framework.console.CommandInterpreter;
15 import org.eclipse.osgi.framework.console.CommandProvider;
16 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
17 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
18 import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
19 import org.opendaylight.controller.sal.binding.api.NotificationListener;
20 import org.opendaylight.controller.sal.binding.api.NotificationService;
21 import org.opendaylight.lispflowmapping.implementation.dao.InMemoryDAO;
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.IQueryAll;
31 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
32 import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
33 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapNotifyHandler;
34 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapReplyHandler;
35 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolverAsync;
36 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServerAsync;
37 import org.opendaylight.lispflowmapping.type.sbplugin.ILispSouthboundPlugin;
38 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.AddMapping;
39 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapNotify;
40 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRegister;
41 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapReply;
42 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest;
43 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.RequestMapping;
44 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainer;
45 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainerBuilder;
46 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.Address;
47 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.address.Ipv4Builder;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
50 import org.osgi.framework.BundleContext;
51 import org.osgi.framework.FrameworkUtil;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 import com.google.common.net.InetAddresses;
57 public class LispMappingService implements CommandProvider, IFlowMapping, BindingAwareConsumer, //
58 IMapReplyHandler, IMapNotifyHandler {
59 protected static final Logger logger = LoggerFactory.getLogger(LispMappingService.class);
61 private ILispDAO lispDao = null;
62 private IMapResolverAsync mapResolver;
63 private IMapServerAsync mapServer;
64 private volatile boolean shouldIterateMask;
65 private volatile boolean shouldAuthenticate;
66 private ThreadLocal<MapReply> tlsMapReply = new ThreadLocal<MapReply>();
67 private ThreadLocal<MapNotify> tlsMapNotify = new ThreadLocal<MapNotify>();
69 private ILispSouthboundPlugin lispSB = null;
71 private ConsumerContext session;
73 public static void main(String[] args) throws Exception {
74 LispMappingService serv = new LispMappingService();
75 serv.setLispDao(new InMemoryDAO());
79 class LispIpv4AddressInMemoryConverter implements ILispTypeConverter<Ipv4Address, Integer> {
82 class LispIpv6AddressInMemoryConverter implements ILispTypeConverter<Ipv6Address, Integer> {
85 class MappingServiceKeyConvertor implements ILispTypeConverter<MappingServiceKey, Integer> {
88 class MappingServiceNoMaskKeyConvertor implements ILispTypeConverter<MappingServiceNoMaskKey, Integer> {
91 void setBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
92 logger.trace("BindingAwareBroker set!");
93 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
94 bindingAwareBroker.registerConsumer(this, bundleContext);
97 void unsetBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
98 logger.debug("BindingAwareBroker was unset in LispMappingService");
101 public void basicInit(ILispDAO dao) {
103 mapResolver = new MapResolver(dao);
104 mapServer = new MapServer(dao);
107 void setLispDao(ILispDAO dao) {
108 logger.trace("LispDAO set in LispMappingService");
110 logger.trace("Registering LispIpv4Address");
111 lispDao.register(LispIpv4AddressInMemoryConverter.class);
112 logger.trace("Registering LispIpv6Address");
113 lispDao.register(LispIpv6AddressInMemoryConverter.class);
114 logger.trace("Registering MappingServiceKey");
115 lispDao.register(MappingServiceKeyConvertor.class);
116 logger.trace("Registering MappingServiceNoMaskKey");
117 lispDao.register(MappingServiceNoMaskKeyConvertor.class);
120 void unsetLispDao(ILispDAO dao) {
121 logger.trace("LispDAO was unset in LispMappingService");
129 registerWithOSGIConsole();
130 logger.info("LISP (RFC6830) Mapping Service init finished");
131 } catch (Throwable t) {
132 logger.error(t.getStackTrace().toString());
136 private void registerWithOSGIConsole() {
137 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
138 bundleContext.registerService(CommandProvider.class.getName(), this, null);
141 public void destroy() {
142 logger.info("LISP (RFC6830) Mapping Service is destroyed!");
147 public void _removeEid(final CommandInterpreter ci) {
148 lispDao.remove(LispAFIConvertor.asIPAfiAddress(ci.nextArgument()));
151 public void _dumpAll(final CommandInterpreter ci) {
152 ci.println("EID\tRLOCs");
153 if (lispDao instanceof IQueryAll) {
154 ((IQueryAll) lispDao).getAll(new IRowVisitor() {
157 public void visitRow(Class<?> keyType, Object keyId, String valueKey, Object value) {
158 String key = keyType.getSimpleName() + "#" + keyId;
159 if (!lastKey.equals(key)) {
161 ci.print(key + "\t");
163 ci.print(valueKey + "=" + value + "\t");
169 ci.println("Not implemented by this DAO");
174 public void _addDefaultPassword(final CommandInterpreter ci) {
175 LispAddressContainerBuilder builder = new LispAddressContainerBuilder();
176 builder.setAddress((Address) (new Ipv4Builder().setIpv4Address(new Ipv4Address("0.0.0.0")).build()));
177 addAuthenticationKey(builder.build(), 0, "password");
180 public String getHelp() {
181 StringBuffer help = new StringBuffer();
182 help.append("---LISP Mapping Service---\n");
183 help.append("\t dumpAll - Dump all current EID -> RLOC mapping\n");
184 help.append("\t removeEid - Remove a single LispIPv4Address Eid\n");
185 return help.toString();
188 public MapReply handleMapRequest(MapRequest request) {
189 tlsMapReply.set(null);
190 mapResolver.handleMapRequest(request, this);
191 // After this invocation we assume that the thread local is filled with
193 return tlsMapReply.get();
197 public MapNotify handleMapRegister(MapRegister mapRegister) {
198 tlsMapNotify.set(null);
199 mapServer.handleMapRegister(mapRegister, this);
200 // After this invocation we assume that the thread local is filled with
202 return tlsMapNotify.get();
205 public String getAuthenticationKey(LispAddressContainer address, int maskLen) {
206 return mapServer.getAuthenticationKey(address, maskLen);
209 public boolean removeAuthenticationKey(LispAddressContainer address, int maskLen) {
210 return mapServer.removeAuthenticationKey(address, maskLen);
213 public boolean addAuthenticationKey(LispAddressContainer address, int maskLen, String key) {
214 return mapServer.addAuthenticationKey(address, maskLen, key);
217 public boolean shouldIterateMask() {
218 return this.shouldIterateMask;
221 public void setShouldIterateMask(boolean shouldIterateMask) {
222 this.shouldIterateMask = shouldIterateMask;
223 this.mapResolver.setShouldIterateMask(shouldIterateMask);
224 this.mapServer.setShouldIterateMask(shouldIterateMask);
227 public void setShouldAuthenticate(boolean shouldAuthenticate) {
228 this.shouldAuthenticate = shouldAuthenticate;
229 this.mapResolver.setShouldAuthenticate(shouldAuthenticate);
230 this.mapServer.setShouldAuthenticate(shouldAuthenticate);
233 public boolean shouldAuthenticate() {
234 return shouldAuthenticate;
237 public void onSessionInitialized(ConsumerContext session) {
238 logger.info("Lisp Consumer session initialized!");
239 NotificationService notificationService = session.getSALService(NotificationService.class);
240 // notificationService.registerNotificationListener(LispNotification.class,
242 notificationService.registerNotificationListener(AddMapping.class, new MapRegisterNotificationHandler());
243 notificationService.registerNotificationListener(RequestMapping.class, new MapRequestNotificationHandler());
244 this.session = session;
247 private class MapRegisterNotificationHandler implements NotificationListener<AddMapping> {
250 public void onNotification(AddMapping mapRegisterNotification) {
251 MapNotify mapNotify = handleMapRegister(mapRegisterNotification.getMapRegister());
252 getLispSB().handleMapNotify(mapNotify,
253 LispNotificationHelper.getInetAddressFromIpAddress(mapRegisterNotification.getTransportAddress().getIpAddress()));
258 private class MapRequestNotificationHandler implements NotificationListener<RequestMapping> {
261 public void onNotification(RequestMapping mapRequestNotification) {
262 MapReply mapReply = handleMapRequest(mapRequestNotification.getMapRequest());
263 getLispSB().handleMapReply(mapReply,
264 LispNotificationHelper.getInetAddressFromIpAddress(mapRequestNotification.getTransportAddress().getIpAddress()));
269 private ILispSouthboundPlugin getLispSB() {
270 if (lispSB == null) {
271 lispSB = session.getRpcService(ILispSouthboundPlugin.class);
276 public void handleMapReply(MapReply reply) {
277 tlsMapReply.set(reply);
280 public void handleMapNotify(MapNotify notify) {
281 tlsMapNotify.set(notify);