/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2015, 2017 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
import org.opendaylight.lispflowmapping.interfaces.mapcache.ILispMapCache;
import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
+import org.opendaylight.lispflowmapping.mapcache.lisp.LispMapCacheStringifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Simple map-cache that works with 'simple' addresses (see lisp-proto.yang). It can do longest prefix matching for IP
*
*/
public class SimpleMapCache implements ILispMapCache {
- private static final Logger LOG = LoggerFactory.getLogger(SimpleMapCache.class);
private ILispDAO dao;
public SimpleMapCache(ILispDAO dao) {
this.dao = dao;
}
- private ILispDAO getVniTable(Eid eid) {
- long vni = 0;
+ private long getVni(Eid eid) {
if (eid.getVirtualNetworkId() == null) {
- vni = 0;
+ return 0;
} else {
- vni = eid.getVirtualNetworkId().getValue();
+ return eid.getVirtualNetworkId().getValue();
}
- return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
+ }
+
+ private ILispDAO getVniTable(Eid eid) {
+ return (ILispDAO) dao.getSpecific(getVni(eid), SubKeys.VNI);
+ }
+
+ private void removeVniTable(Eid eid) {
+ dao.removeSpecific(getVni(eid), SubKeys.VNI);
}
private ILispDAO getOrInstantiateVniTable(Eid eid) {
- long vni = 0;
- if (eid.getVirtualNetworkId() == null) {
- vni = 0;
- } else {
- vni = eid.getVirtualNetworkId().getValue();
- }
+ long vni = getVni(eid);
ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
if (table == null) {
table = dao.putNestedTable(vni, SubKeys.VNI);
return table;
}
- private ILispDAO getXtrIdTable(Eid eid, ILispDAO dao) {
- return (ILispDAO) dao.getSpecific(eid, SubKeys.XTRID_RECORDS);
- }
-
- private ILispDAO getOrInstantiateXtrIdTable(Eid eid, ILispDAO dao) {
- ILispDAO table = (ILispDAO) dao.getSpecific(eid, SubKeys.XTRID_RECORDS);
+ private ILispDAO getOrInstantiateXtrIdTable(Eid eid, ILispDAO lispDAO) {
+ ILispDAO table = (ILispDAO) lispDAO.getSpecific(eid, SubKeys.XTRID_RECORDS);
if (table == null) {
- table = dao.putNestedTable(eid, SubKeys.XTRID_RECORDS);
+ table = lispDAO.putNestedTable(eid, SubKeys.XTRID_RECORDS);
}
return table;
}
// Returns the mapping corresponding to the longest prefix match for eid. eid must be a simple (maskable or not)
// address
- private Object getMappingLpmEid(Eid eid, XtrId xtrId, ILispDAO dao) {
- SimpleImmutableEntry<Eid, Map<String, ?>> daoEntry = dao.getBestPair(MaskUtil.normalize(eid));
+ private Object getMappingLpmEid(Eid eid, XtrId xtrId, ILispDAO lispDAO) {
+ SimpleImmutableEntry<Eid, Map<String, ?>> daoEntry = lispDAO.getBestPair(MaskUtil.normalize(eid));
if (daoEntry != null) {
if (xtrId != null) {
ILispDAO xtrIdTable = (ILispDAO) daoEntry.getValue().get(SubKeys.XTRID_RECORDS);
}
// Returns the list of mappings stored in an xTR-ID DAO
- private List<Object> getXtrIdMappingList(ILispDAO dao) {
- if (dao != null) {
+ private List<Object> getXtrIdMappingList(ILispDAO lispDAO) {
+ if (lispDAO != null) {
final List<Object> records = new ArrayList<>();
- dao.getAll(new IRowVisitor() {
+ lispDAO.getAll(new IRowVisitor() {
public void visitRow(Object keyId, String valueKey, Object value) {
if (valueKey.equals(SubKeys.RECORD)) {
records.add(value);
return null;
}
+ // Returns null for positive mappings, and 0/0 for empty cache.
+ @Override
public Eid getWidestNegativeMapping(Eid eid) {
ILispDAO table = getVniTable(eid);
if (table == null) {
- return null;
+ return MaskUtil.normalize(eid, (short) 0);
}
return table.getWidestNegativePrefix(MaskUtil.normalize(eid));
}
@Override
- public void removeMapping(Eid eid) {
- Eid key = MaskUtil.normalize(eid);
- ILispDAO table = getVniTable(key);
+ public Eid getCoveringLessSpecific(Eid eid) {
+ ILispDAO table = getVniTable(eid);
if (table == null) {
- return;
+ return null;
}
-
- // We intentionally don't remove subscribers, so in case a mapping is re-added, they get notified
- table.removeSpecific(key, SubKeys.RECORD);
- table.removeSpecific(key, SubKeys.SRC_RLOCS);
- table.removeSpecific(key, SubKeys.XTRID_RECORDS);
+ return table.getCoveringLessSpecific(MaskUtil.normalize(eid));
}
@Override
- public void removeMapping(Eid eid, XtrId xtrId) {
- Eid key = MaskUtil.normalize(eid);
- ILispDAO table = getVniTable(key);
+ public Eid getParentPrefix(Eid eid) {
+ ILispDAO table = getVniTable(eid);
if (table == null) {
- return;
- }
- ILispDAO xtrIdTable = getXtrIdTable(key, table);
- if (xtrIdTable == null) {
- return;
+ return null;
}
- xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
+ return table.getParentPrefix(MaskUtil.normalize(eid));
}
@Override
- public void removeXtrIdMappings(Eid eid, List<XtrId> xtrIds) {
- Eid key = MaskUtil.normalize(eid);
- ILispDAO table = getVniTable(key);
+ public Eid getSiblingPrefix(Eid eid) {
+ ILispDAO table = getVniTable(eid);
if (table == null) {
- return;
- }
- ILispDAO xtrIdTable = getXtrIdTable(key, table);
- if (xtrIdTable == null) {
- return;
- }
- for (XtrId xtrId : xtrIds) {
- xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
+ return null;
}
+ return table.getSiblingPrefix(MaskUtil.normalize(eid));
}
@Override
- public void addAuthenticationKey(Eid eid, MappingAuthkey authKey) {
- Eid key = MaskUtil.normalize(eid);
- ILispDAO table = getOrInstantiateVniTable(key);
- table.put(key, new MappingEntry<>(SubKeys.AUTH_KEY, authKey));
+ public Eid getVirtualParentSiblingPrefix(Eid eid) {
+ ILispDAO table = getVniTable(eid);
+ if (table == null) {
+ return null;
+ }
+ return table.getVirtualParentSiblingPrefix(MaskUtil.normalize(eid));
}
- private MappingAuthkey getAuthKeyLpm(Eid prefix, ILispDAO db) {
- short maskLength = MaskUtil.getMaskForAddress(prefix.getAddress());
- while (maskLength >= 0) {
- Eid key = MaskUtil.normalize(prefix, maskLength);
- Object password = db.getSpecific(key, SubKeys.AUTH_KEY);
- if (password != null && password instanceof MappingAuthkey) {
- return (MappingAuthkey) password;
- }
- maskLength -= 1;
+ @Override
+ public Set<Eid> getSubtree(Eid eid) {
+ ILispDAO table = getVniTable(eid);
+ if (table == null) {
+ return Collections.emptySet();
}
- return null;
+ return table.getSubtree(eid);
}
@Override
- public MappingAuthkey getAuthenticationKey(Eid eid) {
+ public void removeMapping(Eid eid) {
ILispDAO table = getVniTable(eid);
if (table == null) {
- return null;
+ return;
}
- if (MaskUtil.isMaskable(eid.getAddress()) && !(eid.getAddress() instanceof SourceDestKey)) {
- return getAuthKeyLpm(eid, table);
- } else {
- Eid key = MaskUtil.normalize(eid);
- Object password = table.getSpecific(key, SubKeys.AUTH_KEY);
- if (password != null && password instanceof MappingAuthkey) {
- return (MappingAuthkey) password;
- } else {
- LOG.warn("Failed to find password!");
- return null;
- }
+
+ Eid key = MaskUtil.normalize(eid);
+ table.remove(key);
+ if (table.isEmpty()) {
+ removeVniTable(eid);
}
}
@Override
- public void removeAuthenticationKey(Eid eid) {
- Eid key = MaskUtil.normalize(eid);
- ILispDAO table = getVniTable(key);
+ public void removeMapping(Eid eid, XtrId xtrId) {
+ List<XtrId> xtrIds = Arrays.asList(xtrId);
+ removeXtrIdMappings(eid, xtrIds);
+ }
+
+ @Override
+ public void removeXtrIdMappings(Eid eid, List<XtrId> xtrIds) {
+ ILispDAO table = getVniTable(eid);
if (table == null) {
return;
}
- table.removeSpecific(key, SubKeys.AUTH_KEY);
+ Eid key = MaskUtil.normalize(eid);
+ ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
+ if (xtrIdTable == null) {
+ return;
+ }
+ for (XtrId xtrId : xtrIds) {
+ xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
+ }
+ if (xtrIdTable.isEmpty()) {
+ table.removeSpecific(key, SubKeys.XTRID_RECORDS);
+ if (table.isEmpty()) {
+ removeVniTable(eid);
+ }
+ }
}
@Override
public void addData(Eid eid, String subKey, Object data) {
+ ILispDAO table = getOrInstantiateVniTable(eid);
Eid key = MaskUtil.normalize(eid);
- ILispDAO table = getOrInstantiateVniTable(key);
table.put(key, new MappingEntry<>(subKey, data));
}
@Override
public Object getData(Eid eid, String subKey) {
- ILispDAO table = getOrInstantiateVniTable(eid);
+ ILispDAO table = getVniTable(eid);
if (table == null) {
return null;
}
@Override
public void removeData(Eid eid, String subKey) {
- ILispDAO table = getOrInstantiateVniTable(eid);
+ ILispDAO table = getVniTable(eid);
if (table == null) {
return;
}
Eid key = MaskUtil.normalize(eid);
table.removeSpecific(key, subKey);
+ if (table.isEmpty()) {
+ removeVniTable(eid);
+ }
}
@Override
public String printMappings() {
- final StringBuffer sb = new StringBuffer();
- sb.append("Keys\tValues\n");
-
- final IRowVisitor innerVisitor = (new IRowVisitor() {
- String lastKey = "";
-
- public void visitRow(Object keyId, String valueKey, Object value) {
- String key = keyId.getClass().getSimpleName() + "#" + keyId;
- if (!lastKey.equals(key)) {
- sb.append("\n" + key + "\t");
- }
- sb.append(valueKey + "=" + value + "\t");
- lastKey = key;
- }
- });
-
- dao.getAll(new IRowVisitor() {
- String lastKey = "";
+ return LispMapCacheStringifier.printSMCMappings(dao);
+ }
- public void visitRow(Object keyId, String valueKey, Object value) {
- String key = keyId.getClass().getSimpleName() + "#" + keyId;
- if (!lastKey.equals(key)) {
- sb.append("\n" + key + "\t");
- }
- if (valueKey.equals(SubKeys.VNI)) {
- sb.append(valueKey + "= { ");
- ((ILispDAO)value).getAll(innerVisitor);
- sb.append("}\t");
- } else {
- sb.append(valueKey + "=" + value + "\t");
- }
- lastKey = key;
- }
- });
- sb.append("\n");
- return sb.toString();
+ @Override
+ public String prettyPrintMappings() {
+ return LispMapCacheStringifier.prettyPrintSMCMappings(dao);
}
}