blob: 2062ccc8e3c5fb79bfb4c6e7ad362cd46ef7425c [file] [log] [blame]
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301/*
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 */
16package org.onosproject.isis.controller.impl.lsdb;
17
chidambar babu344dc812016-05-02 19:13:10 +053018import org.jboss.netty.buffer.ChannelBuffers;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053019import org.onosproject.isis.controller.IsisInterface;
20import org.onosproject.isis.controller.IsisLsdb;
21import org.onosproject.isis.controller.IsisLsdbAge;
22import org.onosproject.isis.controller.IsisLspBin;
23import org.onosproject.isis.controller.IsisMessage;
sunish vk7bdf4d42016-06-24 12:29:43 +053024import org.onosproject.isis.controller.IsisNeighbor;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053025import org.onosproject.isis.controller.IsisPduType;
sunish vk7bdf4d42016-06-24 12:29:43 +053026import org.onosproject.isis.controller.IsisRouterType;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053027import org.onosproject.isis.controller.LspWrapper;
sunish vk7bdf4d42016-06-24 12:29:43 +053028import org.onosproject.isis.controller.impl.Controller;
29import org.onosproject.isis.controller.impl.LspEventConsumer;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053030import org.onosproject.isis.io.isispacket.pdu.LsPdu;
31import org.onosproject.isis.io.util.IsisConstants;
chidambar babu344dc812016-05-02 19:13:10 +053032import org.onosproject.isis.io.util.IsisUtil;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053033import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
sunish vk7bdf4d42016-06-24 12:29:43 +053036import java.util.ArrayList;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053037import java.util.Iterator;
38import java.util.List;
39import java.util.Map;
sunish vk7bdf4d42016-06-24 12:29:43 +053040import java.util.concurrent.ArrayBlockingQueue;
41import java.util.concurrent.BlockingQueue;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053042import java.util.concurrent.ConcurrentHashMap;
43import java.util.concurrent.CopyOnWriteArrayList;
44
45/**
46 * Representation of ISIS link state database.
47 */
48public class DefaultIsisLsdb implements IsisLsdb {
49 private static final Logger log = LoggerFactory.getLogger(DefaultIsisLsdb.class);
50 private Map<String, LspWrapper> isisL1Db = new ConcurrentHashMap<>();
51 private Map<String, LspWrapper> isisL2Db = new ConcurrentHashMap<>();
52 private IsisLsdbAge lsdbAge = null;
sunish vk7bdf4d42016-06-24 12:29:43 +053053 private Controller controller = null;
54 private List<IsisInterface> isisInterfaceList = new ArrayList<>();
chidambar babu344dc812016-05-02 19:13:10 +053055
56
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053057 private int l1LspSeqNo = IsisConstants.STARTLSSEQUENCENUM;
58 private int l2LspSeqNo = IsisConstants.STARTLSSEQUENCENUM;
sunish vk7bdf4d42016-06-24 12:29:43 +053059 private LspEventConsumer queueConsumer = null;
60 private BlockingQueue<LspWrapper> lspForProviderQueue = new ArrayBlockingQueue<>(1024);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053061
62 /**
63 * Creates an instance of ISIS LSDB.
64 */
65 public DefaultIsisLsdb() {
66 lsdbAge = new DefaultIsisLsdbAge();
67 }
68
69 /**
sunish vk7bdf4d42016-06-24 12:29:43 +053070 * Sets the controller instance.
71 *
72 * @param controller controller instance
73 */
74 public void setController(Controller controller) {
75 this.controller = controller;
76 }
77
78 /**
79 * Sets the list of IsisInterface instance.
80 *
81 * @param isisInterfaceList isisInterface instance
82 */
83 public void setIsisInterface(List<IsisInterface> isisInterfaceList) {
84 this.isisInterfaceList = isisInterfaceList;
85 }
86
87 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053088 * Initializes the link state database.
89 */
90 public void initializeDb() {
91 lsdbAge.startDbAging();
sunish vk7bdf4d42016-06-24 12:29:43 +053092 queueConsumer = new LspEventConsumer(lspForProviderQueue, controller);
93 new Thread(queueConsumer).start();
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053094 }
95
96 /**
chidambar babu344dc812016-05-02 19:13:10 +053097 * Sets the level 1 link state sequence number.
98 *
99 * @param l1LspSeqNo link state sequence number
100 */
101 public void setL1LspSeqNo(int l1LspSeqNo) {
102 this.l1LspSeqNo = l1LspSeqNo;
103 }
104
105 /**
106 * Sets the level 2 link state sequence number.
107 *
108 * @param l2LspSeqNo link state sequence number
109 */
110 public void setL2LspSeqNo(int l2LspSeqNo) {
111 this.l2LspSeqNo = l2LspSeqNo;
112 }
sunish vk4b5ce002016-05-09 20:18:35 +0530113
chidambar babu344dc812016-05-02 19:13:10 +0530114 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530115 * Returns the LSDB LSP key.
116 *
117 * @param systemId system ID
118 * @return key
119 */
120 public String lspKey(String systemId) {
121 StringBuilder lspKey = new StringBuilder();
122 lspKey.append(systemId);
123 lspKey.append(".00");
124 lspKey.append("-");
125 lspKey.append("00");
126
127 return lspKey.toString();
128 }
129
130 /**
131 * Returns the neighbor L1 database information.
132 *
133 * @return neighbor L1 database information
134 */
135 public Map<String, LspWrapper> getL1Db() {
136 return isisL1Db;
137 }
138
139 /**
140 * Returns the neighbor L2 database information.
141 *
142 * @return neighbor L2 database information
143 */
144 public Map<String, LspWrapper> getL2Db() {
145 return isisL2Db;
146 }
147
148 /**
149 * Returns the LSDB instance.
150 *
151 * @return LSDB instance
152 */
153 public IsisLsdb isisLsdb() {
154 return this;
155 }
156
157 /**
158 * Returns all LSPs (L1 and L2).
159 *
160 * @param excludeMaxAgeLsp exclude the max age LSPs
161 * @return List of LSPs
162 */
163 public List<LspWrapper> allLspHeaders(boolean excludeMaxAgeLsp) {
chidambar babu344dc812016-05-02 19:13:10 +0530164 List<LspWrapper> summaryList = new CopyOnWriteArrayList<>();
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530165 addLspToHeaderList(summaryList, excludeMaxAgeLsp, isisL1Db);
166 addLspToHeaderList(summaryList, excludeMaxAgeLsp, isisL2Db);
167
168 return summaryList;
169 }
170
171 /**
172 * Adds the LSPs to summary list.
173 *
174 * @param summaryList summary list
175 * @param excludeMaxAgeLsp exclude max age LSP
176 * @param lspMap map of LSP
177 */
178 private void addLspToHeaderList(List summaryList, boolean excludeMaxAgeLsp, Map lspMap) {
179 Iterator slotVals = lspMap.values().iterator();
180 while (slotVals.hasNext()) {
181 LspWrapper wrapper = (LspWrapper) slotVals.next();
182 if (excludeMaxAgeLsp) {
183 //if current age of lsa is max age or lsa present in Max Age bin
184 if (wrapper.remainingLifetime() != 0) {
185 addToList(wrapper, summaryList);
186 }
187 } else {
188 addToList(wrapper, summaryList);
189 }
190 }
191 }
192
193 /**
194 * Adds the LSPWrapper to summary list.
195 *
196 * @param wrapper LSP wrapper instance
197 * @param summList LSP summary list
198 */
199 private void addToList(LspWrapper wrapper, List summList) {
200 //set the current age
201 ((LsPdu) wrapper.lsPdu()).setRemainingLifeTime(wrapper.remainingLifetime());
202 summList.add(wrapper);
203 }
204
205 /**
206 * Finds the LSP from appropriate maps L1 or L2 based on type.
207 *
208 * @param pduType L1 or L2 LSP
209 * @param lspId LSP ID
210 * @return LSP wrapper object
211 */
212 public LspWrapper findLsp(IsisPduType pduType, String lspId) {
213 LspWrapper lspWrapper = null;
214
215 switch (pduType) {
216 case L1LSPDU:
217 lspWrapper = isisL1Db.get(lspId);
218 break;
219 case L2LSPDU:
220 lspWrapper = isisL2Db.get(lspId);
221 break;
222 default:
223 log.debug("Unknown LSP type..!!!");
224 break;
225 }
226
227 //set the current age
228 if (lspWrapper != null) {
229 //set the current age
230 ((DefaultLspWrapper) lspWrapper).lsPdu().setRemainingLifeTime(lspWrapper.remainingLifetime());
231 }
232
233 return lspWrapper;
234 }
235
236 /**
237 * Installs a new self-originated LSP.
238 *
239 * @return true if successfully added
240 */
241 public boolean addLsp(IsisMessage isisMessage, boolean isSelfOriginated, IsisInterface isisInterface) {
242 LsPdu lspdu = (LsPdu) isisMessage;
chidambar babu344dc812016-05-02 19:13:10 +0530243 if (isSelfOriginated) {
244 //Add length and checksum
245 byte[] lspBytes = lspdu.asBytes();
246 lspdu.setPduLength(lspBytes.length);
247 lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
sunish vk7bdf4d42016-06-24 12:29:43 +0530248 IsisConstants.CHECKSUMPOSITION + 1);
chidambar babu344dc812016-05-02 19:13:10 +0530249 byte[] checkSum = {lspBytes[IsisConstants.CHECKSUMPOSITION], lspBytes[IsisConstants.CHECKSUMPOSITION + 1]};
250 lspdu.setCheckSum(ChannelBuffers.copiedBuffer(checkSum).readUnsignedShort());
251 }
sunish vk4b5ce002016-05-09 20:18:35 +0530252
253 DefaultLspWrapper lspWrapper = (DefaultLspWrapper) findLsp(lspdu.isisPduType(), lspdu.lspId());
254 if (lspWrapper == null) {
255 lspWrapper = new DefaultLspWrapper();
256 }
257
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530258 lspWrapper.setLspAgeReceived(IsisConstants.LSPMAXAGE - lspdu.remainingLifeTime());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530259 lspWrapper.setLspType(IsisPduType.get(lspdu.pduType()));
260 lspWrapper.setLsPdu(lspdu);
261 lspWrapper.setAgeCounterWhenReceived(lsdbAge.ageCounter());
262 lspWrapper.setAgeCounterRollOverWhenAdded(lsdbAge.ageCounterRollOver());
263 lspWrapper.setSelfOriginated(isSelfOriginated);
264 lspWrapper.setIsisInterface(isisInterface);
265 lspWrapper.setLsdbAge(lsdbAge);
266 addLsp(lspWrapper, lspdu.lspId());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530267
sunish vk4b5ce002016-05-09 20:18:35 +0530268 log.debug("Added LSp In LSDB: {}", lspWrapper);
sunish vk7bdf4d42016-06-24 12:29:43 +0530269 try {
270 if (!lspWrapper.isSelfOriginated()) {
271 lspWrapper.setLspProcessing(IsisConstants.LSPADDED);
272 lspForProviderQueue.put(lspWrapper);
273 }
274 } catch (Exception e) {
275 log.debug("Added LSp In Blocking queue: {}", lspWrapper);
276 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530277 return true;
278 }
279
280 /**
281 * Adds the LSP to L1 or L2 database.
282 *
283 * @param lspWrapper LSA wrapper instance
284 * @param key key
285 * @return True if added else false
286 */
287 private boolean addLsp(LspWrapper lspWrapper, String key) {
288 //Remove the lsa from bin if exist.
289 removeLspFromBin(lspWrapper);
290
291 switch (lspWrapper.lsPdu().isisPduType()) {
292 case L1LSPDU:
chidambar babu344dc812016-05-02 19:13:10 +0530293 isisL1Db.remove(key);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530294 isisL1Db.put(key, lspWrapper);
295 break;
296 case L2LSPDU:
chidambar babu344dc812016-05-02 19:13:10 +0530297 isisL2Db.remove(key);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530298 isisL2Db.put(key, lspWrapper);
299 break;
300 default:
301 log.debug("Unknown LSP type to add..!!!");
302 break;
303 }
304
305 //add it to bin
chidambar babu344dc812016-05-02 19:13:10 +0530306 Integer binNumber = lsdbAge.age2Bin(IsisConstants.LSPMAXAGE - lspWrapper.lspAgeReceived());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530307 IsisLspBin lspBin = lsdbAge.getLspBin(binNumber);
308 if (lspBin != null) {
309 //remove from existing
310 lspWrapper.setBinNumber(binNumber);
311 lspBin.addIsisLsp(key, lspWrapper);
312 lsdbAge.addLspBin(binNumber, lspBin);
313 log.debug("Added Type {} LSP to LSDB and LSABin[{}], Remaining life time of LSA {}",
sunish vk7bdf4d42016-06-24 12:29:43 +0530314 lspWrapper.lsPdu().isisPduType(),
315 binNumber, lspWrapper.remainingLifetime());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530316 }
sunish vk7bdf4d42016-06-24 12:29:43 +0530317
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530318 return false;
319 }
320
321 /**
322 * Removes LSP from Bin.
323 *
324 * @param lsaWrapper LSP wrapper instance
325 */
326 public void removeLspFromBin(LspWrapper lsaWrapper) {
327 if (lsaWrapper != null) {
328 lsdbAge.removeLspFromBin(lsaWrapper);
329 }
330 }
331
332 /**
333 * Returns new ,latest or old according to the type of ISIS message received.
334 *
335 * @param lsp1 LSP instance
336 * @param lsp2 LSP instance
337 * @return string status
338 */
339 public String isNewerOrSameLsp(IsisMessage lsp1, IsisMessage lsp2) {
340 LsPdu receivedLsp = (LsPdu) lsp1;
341 LsPdu lspFromDb = (LsPdu) lsp2;
chidambar babu344dc812016-05-02 19:13:10 +0530342 if (receivedLsp.sequenceNumber() > lspFromDb.sequenceNumber() ||
343 receivedLsp.checkSum() != lspFromDb.checkSum()) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530344 return "latest";
345 } else if (receivedLsp.sequenceNumber() < lspFromDb.sequenceNumber()) {
346 return "old";
347 } else if (receivedLsp.sequenceNumber() == lspFromDb.sequenceNumber()) {
348 return "same";
349 }
350
351 return "";
352 }
353
354 /**
355 * Returns the sequence number.
356 *
357 * @param lspType type of LSP
358 * @return sequence number
359 */
360 public int lsSequenceNumber(IsisPduType lspType) {
361 switch (lspType) {
362 case L1LSPDU:
363 return l1LspSeqNo++;
364 case L2LSPDU:
365 return l2LspSeqNo++;
366 default:
367 return IsisConstants.STARTLSSEQUENCENUM;
368 }
369 }
370
371 /**
372 * Deletes the given LSP.
373 *
374 * @param lspMessage LSP instance
375 */
376 public void deleteLsp(IsisMessage lspMessage) {
377 LsPdu lsp = (LsPdu) lspMessage;
378 String lspKey = lsp.lspId();
sunish vk7bdf4d42016-06-24 12:29:43 +0530379 LspWrapper lspWrapper = findLsp(lspMessage.isisPduType(), lspKey);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530380 switch (lsp.isisPduType()) {
381 case L1LSPDU:
382 isisL1Db.remove(lspKey);
383 break;
384 case L2LSPDU:
385 isisL2Db.remove(lspKey);
386 break;
387 default:
388 log.debug("Unknown LSP type to remove..!!!");
389 break;
390 }
sunish vk7bdf4d42016-06-24 12:29:43 +0530391
392 try {
393 lspWrapper.setLspProcessing(IsisConstants.LSPREMOVED);
394 lspForProviderQueue.put(lspWrapper);
395 } catch (Exception e) {
396 log.debug("Added LSp In Blocking queue: {}", lspWrapper);
397 }
398 }
399
400 /**
401 * Removes topology information when neighbor down.
402 *
403 * @param neighbor ISIS neighbor instance
404 * @param isisInterface ISIS interface instance
405 */
406 public void removeTopology(IsisNeighbor neighbor, IsisInterface isisInterface) {
407 String lspKey = neighbor.neighborSystemId() + ".00-00";
408 LspWrapper lspWrapper = null;
409 switch (IsisRouterType.get(isisInterface.reservedPacketCircuitType())) {
410 case L1:
411 lspWrapper = findLsp(IsisPduType.L1LSPDU, lspKey);
412 break;
413 case L2:
414 lspWrapper = findLsp(IsisPduType.L2LSPDU, lspKey);
415 break;
416 case L1L2:
417 lspWrapper = findLsp(IsisPduType.L1LSPDU, lspKey);
418 if (lspWrapper == null) {
419 lspWrapper = findLsp(IsisPduType.L2LSPDU, lspKey);
420 }
421 break;
422 default:
423 log.debug("Unknown type");
424 }
425 try {
426 if (lspWrapper != null) {
427 lspWrapper.setLspProcessing(IsisConstants.LSPREMOVED);
428 lspForProviderQueue.put(lspWrapper);
429 }
430 } catch (Exception e) {
431 log.debug("Added LSp In Blocking queue: {}", lspWrapper);
432 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530433 }
sunish vk4b5ce002016-05-09 20:18:35 +0530434}