blob: aab371b5298c5b42bf2733c400c7c37d70764dff [file] [log] [blame]
Jian Li2dbd8a22017-06-08 02:11:25 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Jian Li2dbd8a22017-06-08 02:11:25 +09003 *
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 */
16package org.onosproject.lisp.ctl.impl;
17
18import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
Jian Lif17e0c92017-06-08 18:18:44 +090020import org.onlab.packet.IpPrefix;
Jian Li2dbd8a22017-06-08 02:11:25 +090021import org.onosproject.lisp.ctl.impl.map.ExpireMap;
22import org.onosproject.lisp.ctl.impl.map.ExpireHashMap;
23import org.onosproject.lisp.msg.protocols.DefaultLispProxyMapRecord.DefaultMapWithProxyBuilder;
24import org.onosproject.lisp.msg.protocols.LispEidRecord;
25import org.onosproject.lisp.msg.protocols.LispMapRecord;
26import org.onosproject.lisp.msg.protocols.LispProxyMapRecord;
27import org.onosproject.lisp.msg.types.LispAfiAddress;
28import org.slf4j.Logger;
29
30import java.util.List;
31import java.util.Optional;
32
Jian Lif17e0c92017-06-08 18:18:44 +090033import static org.onosproject.lisp.ctl.impl.util.LispMapUtil.*;
Jian Li2dbd8a22017-06-08 02:11:25 +090034import static org.slf4j.LoggerFactory.getLogger;
Jian Li2dbd8a22017-06-08 02:11:25 +090035
36/**
37 * An expire map based LISP mapping database.
38 * A singleton class that stores EID-RLOC mapping information.
39 */
40public final class LispExpireMapDatabase implements LispMappingDatabase {
41
Ray Milkey3717e602018-02-01 13:49:47 -080042 private static final long MINUTE_TO_MS_UNIT = 60L * 1000L;
Jian Li2dbd8a22017-06-08 02:11:25 +090043
44 private static final Logger log = getLogger(LispExpireMapDatabase.class);
45
46 private final ExpireMap<LispEidRecord, LispProxyMapRecord> map = new ExpireHashMap<>();
47
48 /**
49 * Prevents object instantiation from external.
50 */
51 private LispExpireMapDatabase() {
52 }
53
54 /**
55 * Obtains a singleton instance.
56 *
57 * @return singleton instance
58 */
59 public static LispExpireMapDatabase getInstance() {
60 return SingletonHelper.INSTANCE;
61 }
62
63 @Override
64 public void putMapRecord(LispEidRecord eid, LispMapRecord rloc,
65 boolean proxyMapReply) {
66 LispProxyMapRecord mapWithProxy = new DefaultMapWithProxyBuilder()
67 .withMapRecord(rloc)
68 .withIsProxyMapReply(proxyMapReply)
69 .build();
70 map.put(eid, mapWithProxy, rloc.getRecordTtl() * MINUTE_TO_MS_UNIT);
71 }
72
73 /**
74 * Returns the results whether a given EidRecord is contained in the map.
75 *
76 * @param eid endpoint identifier
77 * @return the results whether a given EidRecord is contained in the map
78 */
79 public boolean hasEidRecord(LispEidRecord eid) {
80 return map.containsKey(eid);
81 }
82
83 @Override
84 public void removeMapRecordByEid(LispEidRecord eid) {
85 map.remove(eid);
86 }
87
88 @Override
89 public void removeAllMapRecords() {
90 map.clear();
91 }
92
93 /**
94 * Obtains all of the EID-RLOC mapping records.
95 *
96 * @return all of the EID-RLOC mapping records
97 */
98 public List<LispMapRecord> getAllMapRecords() {
99
100 List<LispMapRecord> mapRecords = Lists.newArrayList();
101
102 map.values().forEach(value -> mapRecords.add(value.getMapRecord()));
103
104 return mapRecords;
105 }
106
107 @Override
108 public LispMapRecord getMapRecordByEidRecord(LispEidRecord eid,
109 boolean proxyMapReply) {
Jian Lif17e0c92017-06-08 18:18:44 +0900110
111 LispProxyMapRecord record = getMapRecordForClosestParentAddress(getIpPrefixFromEidRecord(eid));
112 if (record != null && record.isProxyMapReply() == proxyMapReply) {
113 return record.getMapRecord();
Jian Li2dbd8a22017-06-08 02:11:25 +0900114 }
115
116 return null;
117 }
118
119 @Override
120 public List<LispMapRecord> getMapRecordByEidRecords(List<LispEidRecord> eids,
121 boolean proxyMapReply) {
122 List<LispMapRecord> mapRecords = Lists.newArrayList();
123 eids.forEach(eidRecord -> {
124 LispMapRecord mapRecord =
125 getMapRecordByEidRecord(eidRecord, proxyMapReply);
126 if (mapRecord != null) {
127 mapRecords.add(mapRecord);
128 }
129 });
130 return ImmutableList.copyOf(mapRecords);
131 }
132
133 /**
134 * Obtains an EID-RLOC mapping record with given EID address.
135 *
136 * @param address endpoint identifier address
137 * @return an EID-RLOC mapping record
138 */
139 public LispMapRecord getMapRecordByEidAddress(LispAfiAddress address) {
140 Optional<LispEidRecord> eidRecord =
141 map.keySet().stream().filter(k ->
142 k.getPrefix().equals(address)).findFirst();
143 return eidRecord.map(lispEidRecord ->
144 map.get(lispEidRecord).getMapRecord()).orElse(null);
145 }
146
147 /**
Jian Lif17e0c92017-06-08 18:18:44 +0900148 * Returns the map record associated with the closest parent address from a
149 * given expire map, or returns null if no such map record is associated
150 * with the address.
151 *
152 * @param prefix IP prefix
153 * @return a map record with the closest parent address, or null if no value
154 * was associated with the address
155 */
156 private LispProxyMapRecord getMapRecordForClosestParentAddress(IpPrefix prefix) {
157 while (prefix != null && prefix.prefixLength() > 0) {
158 LispProxyMapRecord record = map.get(getEidRecordFromIpPrefix(prefix));
159 if (record != null) {
160 return record;
161 }
162 prefix = getParentPrefix(prefix);
163 }
164
165 return null;
166 }
167
168 /**
Jian Li2dbd8a22017-06-08 02:11:25 +0900169 * Prevents object instantiation from external.
170 */
171 private static final class SingletonHelper {
172 private static final String ILLEGAL_ACCESS_MSG = "Should not instantiate this class.";
173 private static final LispExpireMapDatabase INSTANCE = new LispExpireMapDatabase();
174
175 private SingletonHelper() {
176 throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
177 }
178 }
179}