blob: 3be5e896f2d9f907a4f4539c43c4f69a93f29a33 [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 *
Ray Milkey0bb1e102016-11-10 14:51:27 -0800239 * @param isisMessage ISIS message
240 * @param isSelfOriginated is the message self originated?
241 * @param isisInterface ISIS interface
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530242 * @return true if successfully added
243 */
244 public boolean addLsp(IsisMessage isisMessage, boolean isSelfOriginated, IsisInterface isisInterface) {
245 LsPdu lspdu = (LsPdu) isisMessage;
chidambar babu344dc812016-05-02 19:13:10 +0530246 if (isSelfOriginated) {
247 //Add length and checksum
248 byte[] lspBytes = lspdu.asBytes();
249 lspdu.setPduLength(lspBytes.length);
250 lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
sunish vk7bdf4d42016-06-24 12:29:43 +0530251 IsisConstants.CHECKSUMPOSITION + 1);
chidambar babu344dc812016-05-02 19:13:10 +0530252 byte[] checkSum = {lspBytes[IsisConstants.CHECKSUMPOSITION], lspBytes[IsisConstants.CHECKSUMPOSITION + 1]};
253 lspdu.setCheckSum(ChannelBuffers.copiedBuffer(checkSum).readUnsignedShort());
254 }
sunish vk4b5ce002016-05-09 20:18:35 +0530255
256 DefaultLspWrapper lspWrapper = (DefaultLspWrapper) findLsp(lspdu.isisPduType(), lspdu.lspId());
257 if (lspWrapper == null) {
258 lspWrapper = new DefaultLspWrapper();
259 }
260
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530261 lspWrapper.setLspAgeReceived(IsisConstants.LSPMAXAGE - lspdu.remainingLifeTime());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530262 lspWrapper.setLspType(IsisPduType.get(lspdu.pduType()));
263 lspWrapper.setLsPdu(lspdu);
264 lspWrapper.setAgeCounterWhenReceived(lsdbAge.ageCounter());
265 lspWrapper.setAgeCounterRollOverWhenAdded(lsdbAge.ageCounterRollOver());
266 lspWrapper.setSelfOriginated(isSelfOriginated);
267 lspWrapper.setIsisInterface(isisInterface);
268 lspWrapper.setLsdbAge(lsdbAge);
269 addLsp(lspWrapper, lspdu.lspId());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530270
sunish vk4b5ce002016-05-09 20:18:35 +0530271 log.debug("Added LSp In LSDB: {}", lspWrapper);
sunish vk7bdf4d42016-06-24 12:29:43 +0530272 try {
273 if (!lspWrapper.isSelfOriginated()) {
274 lspWrapper.setLspProcessing(IsisConstants.LSPADDED);
275 lspForProviderQueue.put(lspWrapper);
276 }
277 } catch (Exception e) {
278 log.debug("Added LSp In Blocking queue: {}", lspWrapper);
279 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530280 return true;
281 }
282
283 /**
284 * Adds the LSP to L1 or L2 database.
285 *
286 * @param lspWrapper LSA wrapper instance
287 * @param key key
288 * @return True if added else false
289 */
290 private boolean addLsp(LspWrapper lspWrapper, String key) {
291 //Remove the lsa from bin if exist.
292 removeLspFromBin(lspWrapper);
293
294 switch (lspWrapper.lsPdu().isisPduType()) {
295 case L1LSPDU:
chidambar babu344dc812016-05-02 19:13:10 +0530296 isisL1Db.remove(key);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530297 isisL1Db.put(key, lspWrapper);
298 break;
299 case L2LSPDU:
chidambar babu344dc812016-05-02 19:13:10 +0530300 isisL2Db.remove(key);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530301 isisL2Db.put(key, lspWrapper);
302 break;
303 default:
304 log.debug("Unknown LSP type to add..!!!");
305 break;
306 }
307
308 //add it to bin
chidambar babu344dc812016-05-02 19:13:10 +0530309 Integer binNumber = lsdbAge.age2Bin(IsisConstants.LSPMAXAGE - lspWrapper.lspAgeReceived());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530310 IsisLspBin lspBin = lsdbAge.getLspBin(binNumber);
311 if (lspBin != null) {
312 //remove from existing
313 lspWrapper.setBinNumber(binNumber);
314 lspBin.addIsisLsp(key, lspWrapper);
315 lsdbAge.addLspBin(binNumber, lspBin);
316 log.debug("Added Type {} LSP to LSDB and LSABin[{}], Remaining life time of LSA {}",
sunish vk7bdf4d42016-06-24 12:29:43 +0530317 lspWrapper.lsPdu().isisPduType(),
318 binNumber, lspWrapper.remainingLifetime());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530319 }
sunish vk7bdf4d42016-06-24 12:29:43 +0530320
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530321 return false;
322 }
323
324 /**
325 * Removes LSP from Bin.
326 *
327 * @param lsaWrapper LSP wrapper instance
328 */
329 public void removeLspFromBin(LspWrapper lsaWrapper) {
330 if (lsaWrapper != null) {
331 lsdbAge.removeLspFromBin(lsaWrapper);
332 }
333 }
334
335 /**
336 * Returns new ,latest or old according to the type of ISIS message received.
337 *
338 * @param lsp1 LSP instance
339 * @param lsp2 LSP instance
340 * @return string status
341 */
342 public String isNewerOrSameLsp(IsisMessage lsp1, IsisMessage lsp2) {
343 LsPdu receivedLsp = (LsPdu) lsp1;
344 LsPdu lspFromDb = (LsPdu) lsp2;
chidambar babu344dc812016-05-02 19:13:10 +0530345 if (receivedLsp.sequenceNumber() > lspFromDb.sequenceNumber() ||
346 receivedLsp.checkSum() != lspFromDb.checkSum()) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530347 return "latest";
348 } else if (receivedLsp.sequenceNumber() < lspFromDb.sequenceNumber()) {
349 return "old";
350 } else if (receivedLsp.sequenceNumber() == lspFromDb.sequenceNumber()) {
351 return "same";
352 }
353
354 return "";
355 }
356
357 /**
358 * Returns the sequence number.
359 *
360 * @param lspType type of LSP
361 * @return sequence number
362 */
363 public int lsSequenceNumber(IsisPduType lspType) {
364 switch (lspType) {
365 case L1LSPDU:
366 return l1LspSeqNo++;
367 case L2LSPDU:
368 return l2LspSeqNo++;
369 default:
370 return IsisConstants.STARTLSSEQUENCENUM;
371 }
372 }
373
374 /**
375 * Deletes the given LSP.
376 *
377 * @param lspMessage LSP instance
378 */
379 public void deleteLsp(IsisMessage lspMessage) {
380 LsPdu lsp = (LsPdu) lspMessage;
381 String lspKey = lsp.lspId();
sunish vk7bdf4d42016-06-24 12:29:43 +0530382 LspWrapper lspWrapper = findLsp(lspMessage.isisPduType(), lspKey);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530383 switch (lsp.isisPduType()) {
384 case L1LSPDU:
385 isisL1Db.remove(lspKey);
386 break;
387 case L2LSPDU:
388 isisL2Db.remove(lspKey);
389 break;
390 default:
391 log.debug("Unknown LSP type to remove..!!!");
392 break;
393 }
sunish vk7bdf4d42016-06-24 12:29:43 +0530394
395 try {
396 lspWrapper.setLspProcessing(IsisConstants.LSPREMOVED);
397 lspForProviderQueue.put(lspWrapper);
398 } catch (Exception e) {
399 log.debug("Added LSp In Blocking queue: {}", lspWrapper);
400 }
401 }
402
403 /**
404 * Removes topology information when neighbor down.
405 *
406 * @param neighbor ISIS neighbor instance
407 * @param isisInterface ISIS interface instance
408 */
409 public void removeTopology(IsisNeighbor neighbor, IsisInterface isisInterface) {
410 String lspKey = neighbor.neighborSystemId() + ".00-00";
411 LspWrapper lspWrapper = null;
412 switch (IsisRouterType.get(isisInterface.reservedPacketCircuitType())) {
413 case L1:
414 lspWrapper = findLsp(IsisPduType.L1LSPDU, lspKey);
415 break;
416 case L2:
417 lspWrapper = findLsp(IsisPduType.L2LSPDU, lspKey);
418 break;
419 case L1L2:
420 lspWrapper = findLsp(IsisPduType.L1LSPDU, lspKey);
421 if (lspWrapper == null) {
422 lspWrapper = findLsp(IsisPduType.L2LSPDU, lspKey);
423 }
424 break;
425 default:
426 log.debug("Unknown type");
427 }
428 try {
429 if (lspWrapper != null) {
430 lspWrapper.setLspProcessing(IsisConstants.LSPREMOVED);
431 lspForProviderQueue.put(lspWrapper);
432 }
433 } catch (Exception e) {
434 log.debug("Added LSp In Blocking queue: {}", lspWrapper);
435 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530436 }
Ray Milkey0bb1e102016-11-10 14:51:27 -0800437}