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.lisp;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.HashSet;
15 import java.net.InetAddress;
17 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKeyUtil;
18 import org.opendaylight.lispflowmapping.implementation.util.LispNotificationHelper;
19 import org.opendaylight.lispflowmapping.implementation.util.MapRequestUtil;
20 import org.opendaylight.lispflowmapping.implementation.util.MaskUtil;
21 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
22 import org.opendaylight.lispflowmapping.interfaces.dao.IMappingServiceKey;
23 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
24 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceRLOCGroup;
25 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceSubscriberRLOC;
26 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapRequestResultHandler;
27 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolverAsync;
28 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest;
29 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidrecords.EidRecord;
30 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord;
31 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord.Action;
32 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecordBuilder;
33 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainerBuilder;
34 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.locatorrecords.LocatorRecord;
35 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.locatorrecords.LocatorRecordBuilder;
36 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.mapreplymessage.MapReplyBuilder;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 public class MapResolver extends AbstractLispComponent implements IMapResolverAsync {
42 private static final int TTL_RLOC_TIMED_OUT = 1;
43 private static final int TTL_NO_RLOC_KNOWN = 15;
44 protected static final Logger logger = LoggerFactory.getLogger(MapResolver.class);
46 public MapResolver(ILispDAO dao) {
47 this(dao, true, true);
50 public MapResolver(ILispDAO dao, boolean authenticate, boolean iterateMask) {
51 super(dao, authenticate, iterateMask);
54 public void handleMapRequest(MapRequest request, IMapRequestResultHandler callback) {
56 logger.warn("handleMapRequest called while dao is uninitialized");
59 InetAddress itrRloc = MapRequestUtil.selectItrRloc(request);
60 logger.trace("Map-Request itrRloc is " + ((itrRloc == null) ? "MISSING" : itrRloc.toString()));
61 if (request.isPitr()) {
62 if (request.getEidRecord().size() > 0) {
63 EidRecord eid = request.getEidRecord().get(0);
64 Object result = getLocatorsSpecific(eid, ADDRESS_SUBKEY);
65 if (result != null && result instanceof MappingServiceRLOCGroup) {
66 MappingServiceRLOCGroup locatorsGroup = (MappingServiceRLOCGroup) result;
67 if (locatorsGroup != null && locatorsGroup.getRecords().size() > 0) {
68 callback.handleNonProxyMapRequest(request,
69 LispNotificationHelper.getInetAddressFromContainer(locatorsGroup.getRecords().get(0).getLispAddressContainer()));
75 MapReplyBuilder builder = new MapReplyBuilder();
76 builder.setEchoNonceEnabled(false);
77 builder.setProbe(false);
78 builder.setSecurityEnabled(false);
79 builder.setNonce(request.getNonce());
80 builder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
81 for (EidRecord eid : request.getEidRecord()) {
82 EidToLocatorRecordBuilder recordBuilder = new EidToLocatorRecordBuilder();
83 recordBuilder.setRecordTtl(0);
84 recordBuilder.setAction(Action.NoAction);
85 recordBuilder.setAuthoritative(false);
86 recordBuilder.setMapVersion((short) 0);
87 recordBuilder.setMaskLength(eid.getMask());
88 recordBuilder.setLispAddressContainer(eid.getLispAddressContainer());
89 recordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
90 List<MappingServiceRLOCGroup> locators = getLocators(eid);
91 if (locators != null && locators.size() > 0) {
92 addLocatorGroups(recordBuilder, locators);
93 if (itrRloc != null) {
94 MappingServiceSubscriberRLOC subscriberRloc = new MappingServiceSubscriberRLOC(itrRloc);
95 HashSet<MappingServiceSubscriberRLOC> subscribers = getSubscribers(eid.getLispAddressContainer(), eid.getMask());
96 if (subscribers == null) {
97 subscribers = new HashSet<MappingServiceSubscriberRLOC>();
98 } else if (subscribers.contains(subscriberRloc)) {
99 /* If there is an entry already for this subscriberRloc, remove it, so that it gets the new timestamp */
100 subscribers.remove(subscriberRloc);
102 IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid.getLispAddressContainer(), eid.getMask());
103 subscribers.add(subscriberRloc);
104 dao.put(key, new MappingEntry<HashSet<MappingServiceSubscriberRLOC>>(SUBSCRIBERS_SUBKEY, subscribers));
108 .setAction(org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord.Action.NativelyForward);
109 if (getPassword(eid.getLispAddressContainer(), eid.getMask()) != null) {
110 recordBuilder.setRecordTtl(TTL_RLOC_TIMED_OUT);
112 recordBuilder.setRecordTtl(TTL_NO_RLOC_KNOWN);
116 builder.getEidToLocatorRecord().add(recordBuilder.build());
119 callback.handleMapReply(builder.build());
123 private List<MappingServiceRLOCGroup> getLocators(EidRecord eid) {
124 IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid.getLispAddressContainer(), eid.getMask());
125 Map<String, ?> locators = dao.get(key);
126 List<MappingServiceRLOCGroup> result = aggregateLocators(locators);
127 if (shouldIterateMask() && result.isEmpty() && MaskUtil.isMaskable(key.getEID().getAddress())) {
128 result = findMaskLocators(key);
133 private List<MappingServiceRLOCGroup> aggregateLocators(Map<String, ?> locators) {
134 List<MappingServiceRLOCGroup> result = new ArrayList<MappingServiceRLOCGroup>();
135 if (locators != null) {
136 for (Object value : locators.values()) {
137 if (value != null && value instanceof MappingServiceRLOCGroup) {
138 if (!((MappingServiceRLOCGroup) value).getRecords().isEmpty()) {
139 result.add((MappingServiceRLOCGroup) value);
147 private Object getLocatorsSpecific(EidRecord eid, String subkey) {
148 IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid.getLispAddressContainer(), eid.getMask());
149 Object locators = dao.getSpecific(key, subkey);
150 if (shouldIterateMask() && locators == null && MaskUtil.isMaskable(key.getEID().getAddress())) {
151 locators = findMaskLocatorsSpecific(key, subkey);
156 private Object findMaskLocatorsSpecific(IMappingServiceKey key, String subkey) {
157 int mask = key.getMask();
159 key = MappingServiceKeyUtil.generateMappingServiceKey(
160 new LispAddressContainerBuilder().setAddress(MaskUtil.normalize(key.getEID().getAddress(), mask)).build(), mask);
162 Object locators = dao.getSpecific(key, subkey);
163 if (locators != null) {
170 private List<MappingServiceRLOCGroup> findMaskLocators(IMappingServiceKey key) {
171 int mask = key.getMask();
173 key = MappingServiceKeyUtil.generateMappingServiceKey(
174 new LispAddressContainerBuilder().setAddress(MaskUtil.normalize(key.getEID().getAddress(), mask)).build(), mask);
176 Map<String, ?> locators = dao.get(key);
177 if (locators != null) {
178 List<MappingServiceRLOCGroup> result = aggregateLocators(locators);
179 if (result != null && !result.isEmpty()) {
187 private void addLocatorGroups(EidToLocatorRecordBuilder recordBuilder, List<MappingServiceRLOCGroup> rlocs) {
188 for (MappingServiceRLOCGroup rloc : rlocs) {
189 addLocators(recordBuilder, rloc);
190 recordBuilder.setRecordTtl(rloc.getTtl());
194 private void addLocators(EidToLocatorRecordBuilder recordBuilder, MappingServiceRLOCGroup locatorObject) {
195 if (locatorObject == null) {
199 for (LocatorRecord record : locatorObject.getRecords()) {
200 recordBuilder.getLocatorRecord().add(
201 new LocatorRecordBuilder().setLocalLocator(record.isLocalLocator()).setRlocProbed(record.isRlocProbed())
202 .setWeight(record.getWeight()).setPriority(record.getPriority()).setMulticastWeight(record.getMulticastWeight())
203 .setMulticastPriority(record.getMulticastPriority()).setRouted(true)
204 .setLispAddressContainer(record.getLispAddressContainer()).build());
206 recordBuilder.setAction(locatorObject.getAction());
207 recordBuilder.setAuthoritative(locatorObject.isAuthoritative());
208 recordBuilder.setRecordTtl(locatorObject.getTtl());
209 } catch (ClassCastException cce) {