blob: 9aec8e9950488bada304c980b29619d591c7f008 [file] [log] [blame]
Jian Li24f6cc02016-11-01 16:38:40 +09001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Jian Li5e505c62016-12-05 02:44:24 +090016package org.onosproject.lisp.ctl.impl;
Jian Li24f6cc02016-11-01 16:38:40 +090017
Jian Li1118c122016-11-01 21:58:15 +090018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
Jian Licdd276b2016-11-15 15:53:21 +090020import org.onlab.packet.IpPrefix;
Jian Li5e505c62016-12-05 02:44:24 +090021import org.onosproject.lisp.ctl.impl.map.ExpireMap;
22import org.onosproject.lisp.ctl.impl.map.ExpireHashMap;
Jian Licdbc0872016-12-05 17:23:53 +090023import org.onosproject.lisp.msg.protocols.DefaultLispProxyMapRecord.DefaultMapWithProxyBuilder;
Jian Li24f6cc02016-11-01 16:38:40 +090024import org.onosproject.lisp.msg.protocols.LispEidRecord;
25import org.onosproject.lisp.msg.protocols.LispMapRecord;
Jian Licdbc0872016-12-05 17:23:53 +090026import org.onosproject.lisp.msg.protocols.LispProxyMapRecord;
Jian Li24f6cc02016-11-01 16:38:40 +090027import org.onosproject.lisp.msg.types.LispAfiAddress;
28
Jian Li1118c122016-11-01 21:58:15 +090029import java.util.List;
Jian Li24f6cc02016-11-01 16:38:40 +090030import java.util.Optional;
Jian Li24f6cc02016-11-01 16:38:40 +090031
32/**
33 * A singleton class that stores EID-RLOC mapping information.
34 */
Jian Li29986d82016-12-01 03:25:12 +090035public final class LispMappingDatabase {
Jian Li24f6cc02016-11-01 16:38:40 +090036
Jian Li29986d82016-12-01 03:25:12 +090037 private static final long MINUTE_TO_MS_UNIT = 60 * 1000;
38
Jian Licdbc0872016-12-05 17:23:53 +090039 private ExpireMap<LispEidRecord, LispProxyMapRecord> map = new ExpireHashMap<>();
Jian Li29986d82016-12-01 03:25:12 +090040
41 /**
42 * Prevents object instantiation from external.
43 */
44 private LispMappingDatabase() {
45 }
Jian Li24f6cc02016-11-01 16:38:40 +090046
47 /**
48 * Obtains a singleton instance.
49 *
50 * @return singleton instance
51 */
Jian Li29986d82016-12-01 03:25:12 +090052 public static LispMappingDatabase getInstance() {
Jian Li24f6cc02016-11-01 16:38:40 +090053 return SingletonHelper.INSTANCE;
54 }
55
56 /**
57 * Inserts a new EID-RLOC mapping record.
58 *
Jian Licdbc0872016-12-05 17:23:53 +090059 * @param eid endpoint identifier
60 * @param rloc route locator record
61 * @param proxyMapReply proxy map reply flag
Jian Li24f6cc02016-11-01 16:38:40 +090062 */
Jian Licdbc0872016-12-05 17:23:53 +090063 public void putMapRecord(LispEidRecord eid, LispMapRecord rloc,
64 boolean proxyMapReply) {
65 LispProxyMapRecord mapWithProxy = new DefaultMapWithProxyBuilder()
66 .withMapRecord(rloc)
67 .withIsProxyMapReply(proxyMapReply)
68 .build();
69 map.put(eid, mapWithProxy, rloc.getRecordTtl() * MINUTE_TO_MS_UNIT);
Jian Li29986d82016-12-01 03:25:12 +090070 }
71
72 /**
73 * Returns the results whether a given EidRecord is contained in the map.
74 *
75 * @param eid endpoint identifier
76 * @return the results whether a given EidRecord is contained in the map
77 */
78 public boolean hasEidRecord(LispEidRecord eid) {
79 return map.containsKey(eid);
Jian Li24f6cc02016-11-01 16:38:40 +090080 }
81
82 /**
83 * Removes an EID-RLOC mapping record with given endpoint identifier.
84 *
85 * @param eid endpoint identifier
86 */
87 public void removeMapRecordByEid(LispEidRecord eid) {
88 map.remove(eid);
89 }
90
91 /**
Jian Lie5306902016-12-09 00:09:46 +090092 * Obtains all of the EID-RLOC mapping records.
93 *
94 * @return all of the EID-RLOC mapping records
95 */
96 public List<LispMapRecord> getAllMapRecords() {
97
98 List<LispMapRecord> mapRecords = Lists.newArrayList();
99
100 map.values().forEach(value -> mapRecords.add(value.getMapRecord()));
101
102 return mapRecords;
103 }
104
105 /**
Jian Licdbc0872016-12-05 17:23:53 +0900106 * Obtains an EID-RLOC mapping record in accordance with the proxy map reply
107 * flag bit and EID record.
Jian Li24f6cc02016-11-01 16:38:40 +0900108 *
Jian Licdbc0872016-12-05 17:23:53 +0900109 * @param eid endpoint identifier record
110 * @param proxyMapReply proxy map reply flag
Jian Li24f6cc02016-11-01 16:38:40 +0900111 * @return an EID-RLOC mapping record
112 */
Jian Licdbc0872016-12-05 17:23:53 +0900113 public LispMapRecord getMapRecordByEidRecord(LispEidRecord eid, boolean proxyMapReply) {
Jian Licdd276b2016-11-15 15:53:21 +0900114
115 for (LispEidRecord key : map.keySet()) {
Jian Licdbc0872016-12-05 17:23:53 +0900116 if (isInRange(key, eid) && map.get(key) != null
117 && map.get(key).isProxyMapReply() == proxyMapReply) {
118 return map.get(key).getMapRecord();
Jian Licdd276b2016-11-15 15:53:21 +0900119 }
120 }
121
122 return null;
Jian Li24f6cc02016-11-01 16:38:40 +0900123 }
124
125 /**
Jian Licdbc0872016-12-05 17:23:53 +0900126 * Obtains a collection of EID-RLOC mapping record in accordance with the
127 * proxy map reply flag bit and EID record.
Jian Li1118c122016-11-01 21:58:15 +0900128 *
Jian Licdbc0872016-12-05 17:23:53 +0900129 * @param eids endpoint identifier records
130 * @param proxyMapReply proxy map reply flag
Jian Li1118c122016-11-01 21:58:15 +0900131 * @return a collection of EID-RLOC mapping records
132 */
Jian Licdbc0872016-12-05 17:23:53 +0900133 public List<LispMapRecord> getMapRecordByEidRecords(List<LispEidRecord> eids,
134 boolean proxyMapReply) {
Jian Li1118c122016-11-01 21:58:15 +0900135 List<LispMapRecord> mapRecords = Lists.newArrayList();
136 eids.forEach(eidRecord -> {
Jian Licdbc0872016-12-05 17:23:53 +0900137 LispMapRecord mapRecord = getMapRecordByEidRecord(eidRecord, proxyMapReply);
Jian Li1118c122016-11-01 21:58:15 +0900138 if (mapRecord != null) {
139 mapRecords.add(mapRecord);
140 }
141 });
142 return ImmutableList.copyOf(mapRecords);
143 }
144
145 /**
Jian Li24f6cc02016-11-01 16:38:40 +0900146 * Obtains an EID-RLOC mapping record with given EID address.
147 *
148 * @param address endpoint identifier address
149 * @return an EID-RLOC mapping record
150 */
151 public LispMapRecord getMapRecordByEidAddress(LispAfiAddress address) {
152 Optional<LispEidRecord> eidRecord =
153 map.keySet().stream().filter(k -> k.getPrefix().equals(address)).findFirst();
Jian Licdbc0872016-12-05 17:23:53 +0900154 return eidRecord.map(lispEidRecord ->
155 map.get(lispEidRecord).getMapRecord()).orElse(null);
Jian Li24f6cc02016-11-01 16:38:40 +0900156 }
Jian Licdd276b2016-11-15 15:53:21 +0900157
158 /**
159 * Generates CIDR style string from EID record.
160 *
161 * @param eidRecord EID record
162 * @return CIDR style string
163 */
164 private String cidrfy(LispEidRecord eidRecord) {
165 StringBuilder sb = new StringBuilder();
166 sb.append(eidRecord.getPrefix().toString());
167 sb.append("/");
168 sb.append(eidRecord.getMaskLength());
169 return sb.toString();
170 }
171
172 /**
173 * Checks whether the EID record is included in the given EID record.
174 *
175 * @param origin the EID record to be compared
176 * @param compare the EID record to compare
177 * @return boolean result
178 */
179 private boolean isInRange(LispEidRecord origin, LispEidRecord compare) {
180
181 IpPrefix originIpPrefix = IpPrefix.valueOf(cidrfy(origin));
182 IpPrefix compareIpPrefix = IpPrefix.valueOf(cidrfy(compare));
183
184 return originIpPrefix.contains(compareIpPrefix);
185 }
Jian Li29986d82016-12-01 03:25:12 +0900186
187 /**
188 * Prevents object instantiation from external.
189 */
190 private static final class SingletonHelper {
191 private static final String ILLEGAL_ACCESS_MSG = "Should not instantiate this class.";
192 private static final LispMappingDatabase INSTANCE = new LispMappingDatabase();
193
194 private SingletonHelper() {
195 throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
196 }
197 }
Jian Li24f6cc02016-11-01 16:38:40 +0900198}