2 * Copyright (c) 2015 Cisco Systems, 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.mapcache;
11 import java.util.AbstractMap.SimpleImmutableEntry;
12 import java.util.ArrayList;
13 import java.util.List;
16 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
17 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
18 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
19 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
20 import org.opendaylight.lispflowmapping.interfaces.mapcache.ILispMapCache;
21 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * Simple map-cache that works with 'simple' addresses (see lisp-proto.yang). It can do longest prefix matching for IP
34 * @author Florin Coras
35 * @author Lorand Jakab
38 public class SimpleMapCache implements ILispMapCache {
39 private static final Logger LOG = LoggerFactory.getLogger(SimpleMapCache.class);
42 public SimpleMapCache(ILispDAO dao) {
46 private ILispDAO getVniTable(Eid eid) {
48 if (eid.getVirtualNetworkId() == null) {
51 vni = eid.getVirtualNetworkId().getValue();
53 return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
56 private ILispDAO getOrInstantiateVniTable(Eid eid) {
58 if (eid.getVirtualNetworkId() == null) {
61 vni = eid.getVirtualNetworkId().getValue();
63 ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
65 table = dao.putNestedTable(vni, SubKeys.VNI);
70 private ILispDAO getOrInstantiateXtrIdTable(Eid eid, ILispDAO dao) {
71 ILispDAO table = (ILispDAO) dao.getSpecific(eid, SubKeys.XTRID_RECORDS);
73 table = dao.putNestedTable(eid, SubKeys.XTRID_RECORDS);
79 public void addMapping(Eid key, Object value) {
80 addMapping(key, value, null);
84 public void addMapping(Eid key, Object value, Set<IpAddressBinary> sourceRlocs) {
85 Eid eid = MaskUtil.normalize(key);
86 ILispDAO table = getOrInstantiateVniTable(key);
87 table.put(eid, new MappingEntry<>(SubKeys.RECORD, value));
88 if (sourceRlocs != null) {
89 table.put(eid, new MappingEntry<>(SubKeys.SRC_RLOCS, sourceRlocs));
94 public void addMapping(Eid key, XtrId xtrId, Object value) {
95 Eid eid = MaskUtil.normalize(key);
96 ILispDAO table = getOrInstantiateVniTable(key);
97 ILispDAO xtrIdDao = getOrInstantiateXtrIdTable(eid, table);
98 xtrIdDao.put(xtrId, new MappingEntry<>(SubKeys.RECORD, value));
101 // Returns the mapping corresponding to the longest prefix match for eid. eid must be a simple (maskable or not)
103 private Object getMappingLpmEid(Eid eid, XtrId xtrId, ILispDAO dao) {
104 SimpleImmutableEntry<Eid, Map<String, ?>> daoEntry = dao.getBestPair(MaskUtil.normalize(eid));
105 if (daoEntry != null) {
107 ILispDAO xtrIdTable = (ILispDAO) daoEntry.getValue().get(SubKeys.XTRID_RECORDS);
108 if (xtrIdTable != null) {
109 return xtrIdTable.getSpecific(xtrId, SubKeys.RECORD);
112 return daoEntry.getValue().get(SubKeys.RECORD);
119 public Object getMapping(Eid srcEid, Eid dstEid) {
120 final XtrId xtrId = null;
121 return getMapping(dstEid, xtrId);
125 public Object getMapping(Eid eid, XtrId xtrId) {
130 ILispDAO table = getVniTable(eid);
134 return getMappingLpmEid(eid, xtrId, table);
137 // Returns the list of mappings stored in an xTR-ID DAO
138 private List<Object> getXtrIdMappingList(ILispDAO dao) {
140 final List<Object> records = new ArrayList<>();
141 dao.getAll(new IRowVisitor() {
142 public void visitRow(Object keyId, String valueKey, Object value) {
143 if (valueKey.equals(SubKeys.RECORD)) {
154 public List<Object> getAllXtrIdMappings(Eid eid) {
155 ILispDAO table = getVniTable(eid);
159 Map<String, ?> daoEntry = table.getBest(MaskUtil.normalize(eid));
160 if (daoEntry != null) {
161 ILispDAO xtrIdTable = (ILispDAO) daoEntry.get(SubKeys.XTRID_RECORDS);
162 if (xtrIdTable != null) {
163 return getXtrIdMappingList(xtrIdTable);
169 public Eid getWidestNegativeMapping(Eid eid) {
170 ILispDAO table = getVniTable(eid);
174 return table.getWidestNegativePrefix(MaskUtil.normalize(eid));
178 public void removeMapping(Eid eid) {
179 Eid key = MaskUtil.normalize(eid);
180 ILispDAO table = getVniTable(key);
185 // We intentionally don't remove subscribers, so in case a mapping is re-added, they get notified
186 table.removeSpecific(key, SubKeys.RECORD);
187 table.removeSpecific(key, SubKeys.SRC_RLOCS);
188 table.removeSpecific(key, SubKeys.XTRID_RECORDS);
192 public void removeMapping(Eid eid, XtrId xtrId) {
193 Eid key = MaskUtil.normalize(eid);
194 ILispDAO table = getVniTable(key);
198 ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
199 if (xtrIdTable == null) {
202 xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
206 public void removeXtrIdMappings(Eid eid, List<XtrId> xtrIds) {
207 Eid key = MaskUtil.normalize(eid);
208 ILispDAO table = getVniTable(key);
212 ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
213 if (xtrIdTable == null) {
216 for (XtrId xtrId : xtrIds) {
217 xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
222 public void addAuthenticationKey(Eid eid, MappingAuthkey authKey) {
223 Eid key = MaskUtil.normalize(eid);
224 ILispDAO table = getOrInstantiateVniTable(key);
225 table.put(key, new MappingEntry<>(SubKeys.AUTH_KEY, authKey));
228 private MappingAuthkey getAuthKeyLpm(Eid prefix, ILispDAO db) {
229 short maskLength = MaskUtil.getMaskForAddress(prefix.getAddress());
230 while (maskLength >= 0) {
231 Eid key = MaskUtil.normalize(prefix, maskLength);
232 Object password = db.getSpecific(key, SubKeys.AUTH_KEY);
233 if (password != null && password instanceof MappingAuthkey) {
234 return (MappingAuthkey) password;
242 public MappingAuthkey getAuthenticationKey(Eid eid) {
243 ILispDAO table = getVniTable(eid);
247 if (MaskUtil.isMaskable(eid.getAddress()) && !(eid.getAddress() instanceof SourceDestKey)) {
248 return getAuthKeyLpm(eid, table);
250 Eid key = MaskUtil.normalize(eid);
251 Object password = table.getSpecific(key, SubKeys.AUTH_KEY);
252 if (password != null && password instanceof MappingAuthkey) {
253 return (MappingAuthkey) password;
255 LOG.warn("Failed to find password!");
262 public void removeAuthenticationKey(Eid eid) {
263 Eid key = MaskUtil.normalize(eid);
264 ILispDAO table = getVniTable(key);
268 table.removeSpecific(key, SubKeys.AUTH_KEY);
272 public void addData(Eid eid, String subKey, Object data) {
273 Eid key = MaskUtil.normalize(eid);
274 ILispDAO table = getOrInstantiateVniTable(key);
275 table.put(key, new MappingEntry<>(subKey, data));
279 public Object getData(Eid eid, String subKey) {
280 ILispDAO table = getOrInstantiateVniTable(eid);
284 Eid key = MaskUtil.normalize(eid);
285 return table.getSpecific(key, subKey);
289 public void removeData(Eid eid, String subKey) {
290 ILispDAO table = getOrInstantiateVniTable(eid);
294 Eid key = MaskUtil.normalize(eid);
295 table.removeSpecific(key, subKey);
299 public String printMappings() {
300 final StringBuffer sb = new StringBuffer();
301 sb.append("Keys\tValues\n");
303 final IRowVisitor innerVisitor = (new IRowVisitor() {
306 public void visitRow(Object keyId, String valueKey, Object value) {
307 String key = keyId.getClass().getSimpleName() + "#" + keyId;
308 if (!lastKey.equals(key)) {
309 sb.append("\n" + key + "\t");
311 sb.append(valueKey + "=" + value + "\t");
316 dao.getAll(new IRowVisitor() {
319 public void visitRow(Object keyId, String valueKey, Object value) {
320 String key = keyId.getClass().getSimpleName() + "#" + keyId;
321 if (!lastKey.equals(key)) {
322 sb.append("\n" + key + "\t");
324 if (valueKey.equals(SubKeys.VNI)) {
325 sb.append(valueKey + "= { ");
326 ((ILispDAO)value).getAll(innerVisitor);
329 sb.append(valueKey + "=" + value + "\t");
335 return sb.toString();