blob: 4545542e18e0542daa59e9f61ac5890518609cce [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 Licdbc0872016-12-05 17:23:53 +090092 * Obtains an EID-RLOC mapping record in accordance with the proxy map reply
93 * flag bit and EID record.
Jian Li24f6cc02016-11-01 16:38:40 +090094 *
Jian Licdbc0872016-12-05 17:23:53 +090095 * @param eid endpoint identifier record
96 * @param proxyMapReply proxy map reply flag
Jian Li24f6cc02016-11-01 16:38:40 +090097 * @return an EID-RLOC mapping record
98 */
Jian Licdbc0872016-12-05 17:23:53 +090099 public LispMapRecord getMapRecordByEidRecord(LispEidRecord eid, boolean proxyMapReply) {
Jian Licdd276b2016-11-15 15:53:21 +0900100
101 for (LispEidRecord key : map.keySet()) {
Jian Licdbc0872016-12-05 17:23:53 +0900102 if (isInRange(key, eid) && map.get(key) != null
103 && map.get(key).isProxyMapReply() == proxyMapReply) {
104 return map.get(key).getMapRecord();
Jian Licdd276b2016-11-15 15:53:21 +0900105 }
106 }
107
108 return null;
Jian Li24f6cc02016-11-01 16:38:40 +0900109 }
110
111 /**
Jian Licdbc0872016-12-05 17:23:53 +0900112 * Obtains a collection of EID-RLOC mapping record in accordance with the
113 * proxy map reply flag bit and EID record.
Jian Li1118c122016-11-01 21:58:15 +0900114 *
Jian Licdbc0872016-12-05 17:23:53 +0900115 * @param eids endpoint identifier records
116 * @param proxyMapReply proxy map reply flag
Jian Li1118c122016-11-01 21:58:15 +0900117 * @return a collection of EID-RLOC mapping records
118 */
Jian Licdbc0872016-12-05 17:23:53 +0900119 public List<LispMapRecord> getMapRecordByEidRecords(List<LispEidRecord> eids,
120 boolean proxyMapReply) {
Jian Li1118c122016-11-01 21:58:15 +0900121 List<LispMapRecord> mapRecords = Lists.newArrayList();
122 eids.forEach(eidRecord -> {
Jian Licdbc0872016-12-05 17:23:53 +0900123 LispMapRecord mapRecord = getMapRecordByEidRecord(eidRecord, proxyMapReply);
Jian Li1118c122016-11-01 21:58:15 +0900124 if (mapRecord != null) {
125 mapRecords.add(mapRecord);
126 }
127 });
128 return ImmutableList.copyOf(mapRecords);
129 }
130
131 /**
Jian Li24f6cc02016-11-01 16:38:40 +0900132 * Obtains an EID-RLOC mapping record with given EID address.
133 *
134 * @param address endpoint identifier address
135 * @return an EID-RLOC mapping record
136 */
137 public LispMapRecord getMapRecordByEidAddress(LispAfiAddress address) {
138 Optional<LispEidRecord> eidRecord =
139 map.keySet().stream().filter(k -> k.getPrefix().equals(address)).findFirst();
Jian Licdbc0872016-12-05 17:23:53 +0900140 return eidRecord.map(lispEidRecord ->
141 map.get(lispEidRecord).getMapRecord()).orElse(null);
Jian Li24f6cc02016-11-01 16:38:40 +0900142 }
Jian Licdd276b2016-11-15 15:53:21 +0900143
144 /**
145 * Generates CIDR style string from EID record.
146 *
147 * @param eidRecord EID record
148 * @return CIDR style string
149 */
150 private String cidrfy(LispEidRecord eidRecord) {
151 StringBuilder sb = new StringBuilder();
152 sb.append(eidRecord.getPrefix().toString());
153 sb.append("/");
154 sb.append(eidRecord.getMaskLength());
155 return sb.toString();
156 }
157
158 /**
159 * Checks whether the EID record is included in the given EID record.
160 *
161 * @param origin the EID record to be compared
162 * @param compare the EID record to compare
163 * @return boolean result
164 */
165 private boolean isInRange(LispEidRecord origin, LispEidRecord compare) {
166
167 IpPrefix originIpPrefix = IpPrefix.valueOf(cidrfy(origin));
168 IpPrefix compareIpPrefix = IpPrefix.valueOf(cidrfy(compare));
169
170 return originIpPrefix.contains(compareIpPrefix);
171 }
Jian Li29986d82016-12-01 03:25:12 +0900172
173 /**
174 * Prevents object instantiation from external.
175 */
176 private static final class SingletonHelper {
177 private static final String ILLEGAL_ACCESS_MSG = "Should not instantiate this class.";
178 private static final LispMappingDatabase INSTANCE = new LispMappingDatabase();
179
180 private SingletonHelper() {
181 throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
182 }
183 }
Jian Li24f6cc02016-11-01 16:38:40 +0900184}