changed license year
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / lisp / MapResolver.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.lisp;
10
11 import java.util.ArrayList;
12 import java.util.Map;
13
14 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKeyUtil;
15 import org.opendaylight.lispflowmapping.implementation.util.MaskUtil;
16 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
17 import org.opendaylight.lispflowmapping.interfaces.dao.IMappingServiceKey;
18 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceRLOC;
19 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceValue;
20 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapReplyHandler;
21 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolverAsync;
22 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest;
23 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidrecords.EidRecord;
24 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord;
25 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord.Action;
26 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecordBuilder;
27 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainerBuilder;
28 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.locatorrecords.LocatorRecord;
29 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.locatorrecords.LocatorRecordBuilder;
30 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.mapreplymessage.MapReplyBuilder;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 public class MapResolver implements IMapResolverAsync {
35     private static final int TTL_RLOC_TIMED_OUT = 1;
36     private static final int TTL_NO_RLOC_KNOWN = 15;
37     private ILispDAO dao;
38     private volatile boolean shouldAuthenticate;
39     private volatile boolean shouldIterateMask;
40     protected static final Logger logger = LoggerFactory.getLogger(MapResolver.class);
41
42     public MapResolver(ILispDAO dao) {
43         this(dao, true, true);
44     }
45
46     public MapResolver(ILispDAO dao, boolean authenticate, boolean iterateMask) {
47         this.dao = dao;
48         this.shouldAuthenticate = authenticate;
49         this.shouldIterateMask = iterateMask;
50     }
51
52     public void handleMapRequest(MapRequest request, IMapReplyHandler callback) {
53         if (dao == null) {
54             logger.warn("handleMapRequest called while dao is uninitialized");
55         } else {
56             MapReplyBuilder builder = new MapReplyBuilder();
57             builder.setEchoNonceEnabled(false);
58             builder.setProbe(false);
59             builder.setSecurityEnabled(false);
60             builder.setNonce(request.getNonce());
61             builder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
62             for (EidRecord eid : request.getEidRecord()) {
63                 EidToLocatorRecordBuilder recordBuilder = new EidToLocatorRecordBuilder();
64                 recordBuilder.setRecordTtl(0);
65                 recordBuilder.setAction(Action.NoAction);
66                 recordBuilder.setAuthoritative(false);
67                 recordBuilder.setMapVersion((short) 0);
68                 recordBuilder.setMaskLength(eid.getMask());
69                 recordBuilder.setLispAddressContainer(eid.getLispAddressContainer());
70                 recordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
71                 IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid.getLispAddressContainer(), eid.getMask());
72                 Map<String, ?> locators = dao.get(key);
73                 if (shouldIterateMask() && locators == null && MaskUtil.isMaskable(key.getEID().getAddress())) {
74                     locators = findMaskLocators(key);
75                 }
76                 if (locators != null) {
77                     MappingServiceValue value = (MappingServiceValue) locators.get("value");
78
79                     if (value.getRlocs() != null && value.getRlocs().size() > 0) {
80                         addLocators(recordBuilder, value);
81                     } else {
82                         recordBuilder
83                                 .setAction(org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord.Action.NativelyForward);
84                         recordBuilder.setRecordTtl(TTL_RLOC_TIMED_OUT);
85                     }
86                 } else {
87                     recordBuilder
88                             .setAction(org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord.Action.NativelyForward);
89                     recordBuilder.setRecordTtl(TTL_NO_RLOC_KNOWN);
90                 }
91                 builder.getEidToLocatorRecord().add(recordBuilder.build());
92             }
93             callback.handleMapReply(builder.build());
94         }
95     }
96
97     private Map<String, ?> findMaskLocators(IMappingServiceKey key) {
98         int mask = key.getMask();
99         while (mask > 0) {
100             key = MappingServiceKeyUtil.generateMappingServiceKey(
101                     new LispAddressContainerBuilder().setAddress(MaskUtil.normalize(key.getEID().getAddress(), mask)).build(), mask);
102             mask--;
103             Map<String, ?> locators = dao.get(key);
104             if (locators != null) {
105                 return locators;
106             }
107         }
108         return null;
109     }
110
111     private void addLocators(EidToLocatorRecordBuilder recordBuilder, MappingServiceValue value) {
112         for (MappingServiceRLOC rloc : value.getRlocs()) {
113             addLocator(recordBuilder, rloc);
114             recordBuilder.setRecordTtl(rloc.getTtl());
115         }
116     }
117
118     private void addLocator(EidToLocatorRecordBuilder recordBuilder, MappingServiceRLOC locatorObject) {
119         if (locatorObject == null) {
120             return;
121         }
122         try {
123             recordBuilder.getLocatorRecord().add(
124                     new LocatorRecordBuilder().setLocalLocator(locatorObject.getRecord().isLocalLocator())
125                             .setRlocProbed(locatorObject.getRecord().isRlocProbed()).setWeight(locatorObject.getRecord().getWeight())
126                             .setPriority(locatorObject.getRecord().getPriority()).setMulticastWeight(locatorObject.getRecord().getMulticastWeight())
127                             .setMulticastPriority(locatorObject.getRecord().getMulticastPriority()).setRouted(true)
128                             .setLispAddressContainer(locatorObject.getRecord().getLispAddressContainer()).build());
129             recordBuilder.setAction(locatorObject.getAction());
130             recordBuilder.setAuthoritative(locatorObject.isAuthoritative());
131             recordBuilder.setRecordTtl(locatorObject.getTtl());
132         } catch (ClassCastException cce) {
133         }
134     }
135
136     public boolean shouldIterateMask() {
137         return shouldIterateMask;
138     }
139
140     public boolean shouldAuthenticate() {
141         return shouldAuthenticate;
142     }
143
144     public void setShouldIterateMask(boolean shouldIterateMask) {
145         this.shouldIterateMask = shouldIterateMask;
146     }
147
148     public void setShouldAuthenticate(boolean shouldAuthenticate) {
149         this.shouldAuthenticate = shouldAuthenticate;
150     }
151
152 }