2 * Copyright (c) 2015, 2017 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.Arrays;
14 import java.util.Collections;
15 import java.util.List;
18 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
19 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
20 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
21 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
22 import org.opendaylight.lispflowmapping.interfaces.mapcache.ILispMapCache;
23 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
24 import org.opendaylight.lispflowmapping.mapcache.lisp.LispMapCacheStringifier;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
30 * Simple map-cache that works with 'simple' addresses (see lisp-proto.yang). It can do longest prefix matching for IP
33 * @author Florin Coras
34 * @author Lorand Jakab
37 public class SimpleMapCache implements ILispMapCache {
40 public SimpleMapCache(ILispDAO dao) {
44 private long getVni(Eid eid) {
45 if (eid.getVirtualNetworkId() == null) {
48 return eid.getVirtualNetworkId().getValue();
52 private ILispDAO getVniTable(Eid eid) {
53 return (ILispDAO) dao.getSpecific(getVni(eid), SubKeys.VNI);
56 private void removeVniTable(Eid eid) {
57 dao.removeSpecific(getVni(eid), SubKeys.VNI);
60 private ILispDAO getOrInstantiateVniTable(Eid eid) {
61 long vni = getVni(eid);
62 ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
64 table = dao.putNestedTable(vni, SubKeys.VNI);
69 private ILispDAO getOrInstantiateXtrIdTable(Eid eid, ILispDAO lispDAO) {
70 ILispDAO table = (ILispDAO) lispDAO.getSpecific(eid, SubKeys.XTRID_RECORDS);
72 table = lispDAO.putNestedTable(eid, SubKeys.XTRID_RECORDS);
78 public void addMapping(Eid key, Object value) {
79 addMapping(key, value, null);
83 public void addMapping(Eid key, Object value, Set<IpAddressBinary> sourceRlocs) {
84 Eid eid = MaskUtil.normalize(key);
85 ILispDAO table = getOrInstantiateVniTable(key);
86 table.put(eid, new MappingEntry<>(SubKeys.RECORD, value));
87 if (sourceRlocs != null) {
88 table.put(eid, new MappingEntry<>(SubKeys.SRC_RLOCS, sourceRlocs));
93 public void addMapping(Eid key, XtrId xtrId, Object value) {
94 Eid eid = MaskUtil.normalize(key);
95 ILispDAO table = getOrInstantiateVniTable(key);
96 ILispDAO xtrIdDao = getOrInstantiateXtrIdTable(eid, table);
97 xtrIdDao.put(xtrId, new MappingEntry<>(SubKeys.RECORD, value));
100 // Returns the mapping corresponding to the longest prefix match for eid. eid must be a simple (maskable or not)
102 private Object getMappingLpmEid(Eid eid, XtrId xtrId, ILispDAO lispDAO) {
103 SimpleImmutableEntry<Eid, Map<String, ?>> daoEntry = lispDAO.getBestPair(MaskUtil.normalize(eid));
104 if (daoEntry != null) {
106 ILispDAO xtrIdTable = (ILispDAO) daoEntry.getValue().get(SubKeys.XTRID_RECORDS);
107 if (xtrIdTable != null) {
108 return xtrIdTable.getSpecific(xtrId, SubKeys.RECORD);
111 return daoEntry.getValue().get(SubKeys.RECORD);
118 public Object getMapping(Eid srcEid, Eid dstEid) {
119 final XtrId xtrId = null;
120 return getMapping(dstEid, xtrId);
124 public Object getMapping(Eid eid, XtrId xtrId) {
129 ILispDAO table = getVniTable(eid);
133 return getMappingLpmEid(eid, xtrId, table);
136 // Returns the list of mappings stored in an xTR-ID DAO
137 private List<Object> getXtrIdMappingList(ILispDAO lispDAO) {
138 if (lispDAO != null) {
139 final List<Object> records = new ArrayList<>();
140 lispDAO.getAll(new IRowVisitor() {
141 public void visitRow(Object keyId, String valueKey, Object value) {
142 if (valueKey.equals(SubKeys.RECORD)) {
153 public List<Object> getAllXtrIdMappings(Eid eid) {
154 ILispDAO table = getVniTable(eid);
158 Map<String, ?> daoEntry = table.getBest(MaskUtil.normalize(eid));
159 if (daoEntry != null) {
160 ILispDAO xtrIdTable = (ILispDAO) daoEntry.get(SubKeys.XTRID_RECORDS);
161 if (xtrIdTable != null) {
162 return getXtrIdMappingList(xtrIdTable);
168 // Returns null for positive mappings, and 0/0 for empty cache.
170 public Eid getWidestNegativeMapping(Eid eid) {
171 ILispDAO table = getVniTable(eid);
173 return MaskUtil.normalize(eid, (short) 0);
175 return table.getWidestNegativePrefix(MaskUtil.normalize(eid));
179 public Eid getCoveringLessSpecific(Eid eid) {
180 ILispDAO table = getVniTable(eid);
184 return table.getCoveringLessSpecific(MaskUtil.normalize(eid));
188 public Eid getParentPrefix(Eid eid) {
189 ILispDAO table = getVniTable(eid);
193 return table.getParentPrefix(MaskUtil.normalize(eid));
197 public Eid getSiblingPrefix(Eid eid) {
198 ILispDAO table = getVniTable(eid);
202 return table.getSiblingPrefix(MaskUtil.normalize(eid));
206 public Eid getVirtualParentSiblingPrefix(Eid eid) {
207 ILispDAO table = getVniTable(eid);
211 return table.getVirtualParentSiblingPrefix(MaskUtil.normalize(eid));
215 public Set<Eid> getSubtree(Eid eid) {
216 ILispDAO table = getVniTable(eid);
218 return Collections.emptySet();
220 return table.getSubtree(eid);
224 public void removeMapping(Eid eid) {
225 ILispDAO table = getVniTable(eid);
230 Eid key = MaskUtil.normalize(eid);
232 if (table.isEmpty()) {
238 public void removeMapping(Eid eid, XtrId xtrId) {
239 List<XtrId> xtrIds = Arrays.asList(xtrId);
240 removeXtrIdMappings(eid, xtrIds);
244 public void removeXtrIdMappings(Eid eid, List<XtrId> xtrIds) {
245 ILispDAO table = getVniTable(eid);
249 Eid key = MaskUtil.normalize(eid);
250 ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
251 if (xtrIdTable == null) {
254 for (XtrId xtrId : xtrIds) {
255 xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
257 if (xtrIdTable.isEmpty()) {
258 table.removeSpecific(key, SubKeys.XTRID_RECORDS);
259 if (table.isEmpty()) {
266 public void addData(Eid eid, String subKey, Object data) {
267 ILispDAO table = getOrInstantiateVniTable(eid);
268 Eid key = MaskUtil.normalize(eid);
269 table.put(key, new MappingEntry<>(subKey, data));
273 public Object getData(Eid eid, String subKey) {
274 ILispDAO table = getVniTable(eid);
278 Eid key = MaskUtil.normalize(eid);
279 return table.getSpecific(key, subKey);
283 public void removeData(Eid eid, String subKey) {
284 ILispDAO table = getVniTable(eid);
288 Eid key = MaskUtil.normalize(eid);
289 table.removeSpecific(key, subKey);
290 if (table.isEmpty()) {
296 public String printMappings() {
297 return LispMapCacheStringifier.printSMCMappings(dao);
301 public String prettyPrintMappings() {
302 return LispMapCacheStringifier.prettyPrintSMCMappings(dao);