Separate authentication key in-memory storage
[lispflowmapping.git] / mappingservice / mapcache / src / main / java / org / opendaylight / lispflowmapping / mapcache / AuthKeyDb.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.lispflowmapping.mapcache;
10
11 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
12 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
13 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
14 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
15 import org.opendaylight.lispflowmapping.interfaces.mapcache.IAuthKeyDb;
16 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 /**
24  * Simple in-memory database for authentication keys, that works with 'simple' addresses (see lisp-proto.yang). It can
25  * do longest prefix matching for IP addresses.
26  *
27  * @author Lorand Jakab
28  *
29  */
30 public class AuthKeyDb implements IAuthKeyDb {
31     private static final Logger LOG = LoggerFactory.getLogger(AuthKeyDb.class);
32     private ILispDAO dao;
33
34     public AuthKeyDb(ILispDAO dao) {
35         this.dao = dao;
36     }
37
38     private ILispDAO getVniTable(Eid eid) {
39         long vni = 0;
40         if (eid.getVirtualNetworkId() == null) {
41             vni = 0;
42         } else {
43             vni = eid.getVirtualNetworkId().getValue();
44         }
45         return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
46     }
47
48     private ILispDAO getOrInstantiateVniTable(Eid eid) {
49         long vni = 0;
50         if (eid.getVirtualNetworkId() == null) {
51             vni = 0;
52         } else {
53             vni = eid.getVirtualNetworkId().getValue();
54         }
55         ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
56         if (table == null) {
57             table = dao.putNestedTable(vni, SubKeys.VNI);
58         }
59         return table;
60     }
61
62     @Override
63     public void addAuthenticationKey(Eid eid, MappingAuthkey authKey) {
64         Eid key = MaskUtil.normalize(eid);
65         ILispDAO table = getOrInstantiateVniTable(key);
66         table.put(key, new MappingEntry<>(SubKeys.AUTH_KEY, authKey));
67     }
68
69     private MappingAuthkey getAuthKeyLpm(Eid prefix, ILispDAO db) {
70         short maskLength = MaskUtil.getMaskForAddress(prefix.getAddress());
71         while (maskLength >= 0) {
72             Eid key = MaskUtil.normalize(prefix, maskLength);
73             Object password = db.getSpecific(key, SubKeys.AUTH_KEY);
74             if (password != null && password instanceof MappingAuthkey) {
75                 return (MappingAuthkey) password;
76             }
77             maskLength -= 1;
78         }
79         return null;
80     }
81
82     /*
83      * Retrieves authentication key from the database. As opposed to the mapping cache, Source/Dest keys are treated as
84      * exact match keys here, and a two level longest prefix match is NOT performed.
85      */
86     @Override
87     public MappingAuthkey getAuthenticationKey(Eid eid) {
88         ILispDAO table = getVniTable(eid);
89         if (table == null) {
90             return null;
91         }
92         if (MaskUtil.isMaskable(eid.getAddress()) && !(eid.getAddress() instanceof SourceDestKey)) {
93             return getAuthKeyLpm(eid, table);
94         } else {
95             Eid key = MaskUtil.normalize(eid);
96             Object password = table.getSpecific(key, SubKeys.AUTH_KEY);
97             if (password != null && password instanceof MappingAuthkey) {
98                 return (MappingAuthkey) password;
99             } else {
100                 LOG.warn("Failed to find password!");
101                 return null;
102             }
103         }
104     }
105
106     @Override
107     public void removeAuthenticationKey(Eid eid) {
108         Eid key = MaskUtil.normalize(eid);
109         ILispDAO table = getVniTable(key);
110         if (table == null) {
111             return;
112         }
113         table.removeSpecific(key, SubKeys.AUTH_KEY);
114     }
115
116     @Override
117     public String printKeys() {
118         final StringBuffer sb = new StringBuffer();
119         sb.append("Keys\tValues\n");
120
121         final IRowVisitor innerVisitor = (new IRowVisitor() {
122             String lastKey = "";
123
124             public void visitRow(Object keyId, String valueKey, Object value) {
125                 String key = keyId.getClass().getSimpleName() + "#" + keyId;
126                 if (!lastKey.equals(key)) {
127                     sb.append("\n" + key + "\t");
128                 }
129                 sb.append(valueKey + "=" + value + "\t");
130                 lastKey = key;
131             }
132         });
133
134         dao.getAll(new IRowVisitor() {
135             String lastKey = "";
136
137             public void visitRow(Object keyId, String valueKey, Object value) {
138                 String key = keyId.getClass().getSimpleName() + "#" + keyId;
139                 if (!lastKey.equals(key)) {
140                     sb.append("\n" + key + "\t");
141                 }
142                 if (valueKey.equals(SubKeys.VNI)) {
143                     sb.append(valueKey + "= { ");
144                     ((ILispDAO)value).getAll(innerVisitor);
145                     sb.append("}\t");
146                 } else {
147                     sb.append(valueKey + "=" + value + "\t");
148                 }
149                 lastKey = key;
150             }
151         });
152         sb.append("\n");
153         return sb.toString();
154     }
155 }