/* * Copyright (c) 2016 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, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.lispflowmapping.mapcache; import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO; import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry; import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys; import org.opendaylight.lispflowmapping.interfaces.mapcache.IAuthKeyDb; import org.opendaylight.lispflowmapping.lisp.util.MaskUtil; import org.opendaylight.lispflowmapping.mapcache.lisp.LispMapCacheStringifier; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey; 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 in-memory database for authentication keys, that works with 'simple' addresses (see lisp-proto.yang). It can * do longest prefix matching for IP addresses. * * @author Lorand Jakab * */ public class AuthKeyDb implements IAuthKeyDb { private static final Logger LOG = LoggerFactory.getLogger(AuthKeyDb.class); private ILispDAO dao; public AuthKeyDb(ILispDAO dao) { this.dao = dao; } private ILispDAO getVniTable(Eid eid) { long vni = 0; if (eid.getVirtualNetworkId() == null) { vni = 0; } else { vni = eid.getVirtualNetworkId().getValue(); } return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI); } private ILispDAO getOrInstantiateVniTable(Eid eid) { long vni = 0; if (eid.getVirtualNetworkId() == null) { vni = 0; } else { vni = eid.getVirtualNetworkId().getValue(); } ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI); if (table == null) { table = dao.putNestedTable(vni, SubKeys.VNI); } return table; } @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)); } 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; } return null; } /* * Retrieves authentication key from the database. As opposed to the mapping cache, Source/Dest keys are treated as * exact match keys here, and a two level longest prefix match is NOT performed. */ @Override public MappingAuthkey getAuthenticationKey(Eid eid) { ILispDAO table = getVniTable(eid); if (table == null) { return null; } 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; } } } @Override public void removeAuthenticationKey(Eid eid) { Eid key = MaskUtil.normalize(eid); ILispDAO table = getVniTable(key); if (table == null) { return; } table.removeSpecific(key, SubKeys.AUTH_KEY); } @Override public String printKeys() { return LispMapCacheStringifier.printKeys(dao); } }