blob: f4f421bafa1486fd2f438d146ac4fde5c7b61bec [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 Li24f6cc02016-11-01 16:38:40 +090023import org.onosproject.lisp.msg.protocols.LispEidRecord;
24import org.onosproject.lisp.msg.protocols.LispMapRecord;
25import org.onosproject.lisp.msg.types.LispAfiAddress;
26
Jian Li1118c122016-11-01 21:58:15 +090027import java.util.List;
Jian Li24f6cc02016-11-01 16:38:40 +090028import java.util.Optional;
Jian Li24f6cc02016-11-01 16:38:40 +090029
30/**
31 * A singleton class that stores EID-RLOC mapping information.
32 */
Jian Li29986d82016-12-01 03:25:12 +090033public final class LispMappingDatabase {
Jian Li24f6cc02016-11-01 16:38:40 +090034
Jian Li29986d82016-12-01 03:25:12 +090035 private static final long MINUTE_TO_MS_UNIT = 60 * 1000;
36
37 private ExpireMap<LispEidRecord, LispMapRecord> map = new ExpireHashMap<>();
38
39 /**
40 * Prevents object instantiation from external.
41 */
42 private LispMappingDatabase() {
43 }
Jian Li24f6cc02016-11-01 16:38:40 +090044
45 /**
46 * Obtains a singleton instance.
47 *
48 * @return singleton instance
49 */
Jian Li29986d82016-12-01 03:25:12 +090050 public static LispMappingDatabase getInstance() {
Jian Li24f6cc02016-11-01 16:38:40 +090051 return SingletonHelper.INSTANCE;
52 }
53
54 /**
55 * Inserts a new EID-RLOC mapping record.
56 *
57 * @param eid endpoint identifier
58 * @param rloc route locator record
59 */
Jian Li29986d82016-12-01 03:25:12 +090060 public void putMapRecord(LispEidRecord eid, LispMapRecord rloc) {
61 map.put(eid, rloc, rloc.getRecordTtl() * MINUTE_TO_MS_UNIT);
62 }
63
64 /**
65 * Returns the results whether a given EidRecord is contained in the map.
66 *
67 * @param eid endpoint identifier
68 * @return the results whether a given EidRecord is contained in the map
69 */
70 public boolean hasEidRecord(LispEidRecord eid) {
71 return map.containsKey(eid);
Jian Li24f6cc02016-11-01 16:38:40 +090072 }
73
74 /**
75 * Removes an EID-RLOC mapping record with given endpoint identifier.
76 *
77 * @param eid endpoint identifier
78 */
79 public void removeMapRecordByEid(LispEidRecord eid) {
80 map.remove(eid);
81 }
82
83 /**
84 * Obtains an EID-RLOC mapping record with given EID record.
85 *
86 * @param eid endpoint identifier record
87 * @return an EID-RLOC mapping record
88 */
89 public LispMapRecord getMapRecordByEidRecord(LispEidRecord eid) {
Jian Licdd276b2016-11-15 15:53:21 +090090
91 for (LispEidRecord key : map.keySet()) {
92 if (isInRange(key, eid)) {
93 return map.get(key);
94 }
95 }
96
97 return null;
Jian Li24f6cc02016-11-01 16:38:40 +090098 }
99
100 /**
Jian Li1118c122016-11-01 21:58:15 +0900101 * Obtains a collection of EID-RLOC mapping records with given EID records.
102 *
103 * @param eids endpoint identifier records
104 * @return a collection of EID-RLOC mapping records
105 */
106 public List<LispMapRecord> getMapRecordByEidRecords(List<LispEidRecord> eids) {
107 List<LispMapRecord> mapRecords = Lists.newArrayList();
108 eids.forEach(eidRecord -> {
109 LispMapRecord mapRecord = getMapRecordByEidRecord(eidRecord);
110 if (mapRecord != null) {
111 mapRecords.add(mapRecord);
112 }
113 });
114 return ImmutableList.copyOf(mapRecords);
115 }
116
117 /**
Jian Li24f6cc02016-11-01 16:38:40 +0900118 * Obtains an EID-RLOC mapping record with given EID address.
119 *
120 * @param address endpoint identifier address
121 * @return an EID-RLOC mapping record
122 */
123 public LispMapRecord getMapRecordByEidAddress(LispAfiAddress address) {
124 Optional<LispEidRecord> eidRecord =
125 map.keySet().stream().filter(k -> k.getPrefix().equals(address)).findFirst();
Jian Li29986d82016-12-01 03:25:12 +0900126 return eidRecord.map(lispEidRecord -> map.get(lispEidRecord)).orElse(null);
Jian Li24f6cc02016-11-01 16:38:40 +0900127 }
Jian Licdd276b2016-11-15 15:53:21 +0900128
129 /**
130 * Generates CIDR style string from EID record.
131 *
132 * @param eidRecord EID record
133 * @return CIDR style string
134 */
135 private String cidrfy(LispEidRecord eidRecord) {
136 StringBuilder sb = new StringBuilder();
137 sb.append(eidRecord.getPrefix().toString());
138 sb.append("/");
139 sb.append(eidRecord.getMaskLength());
140 return sb.toString();
141 }
142
143 /**
144 * Checks whether the EID record is included in the given EID record.
145 *
146 * @param origin the EID record to be compared
147 * @param compare the EID record to compare
148 * @return boolean result
149 */
150 private boolean isInRange(LispEidRecord origin, LispEidRecord compare) {
151
152 IpPrefix originIpPrefix = IpPrefix.valueOf(cidrfy(origin));
153 IpPrefix compareIpPrefix = IpPrefix.valueOf(cidrfy(compare));
154
155 return originIpPrefix.contains(compareIpPrefix);
156 }
Jian Li29986d82016-12-01 03:25:12 +0900157
158 /**
159 * Prevents object instantiation from external.
160 */
161 private static final class SingletonHelper {
162 private static final String ILLEGAL_ACCESS_MSG = "Should not instantiate this class.";
163 private static final LispMappingDatabase INSTANCE = new LispMappingDatabase();
164
165 private SingletonHelper() {
166 throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
167 }
168 }
Jian Li24f6cc02016-11-01 16:38:40 +0900169}