blob: f76a4db6de80751ff481b682e510ec4b81c3d9c4 [file] [log] [blame]
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05303 *
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.ospf.controller.lsdb;
17
18import com.google.common.base.Objects;
19import org.onosproject.ospf.controller.LsaBin;
20import org.onosproject.ospf.controller.LsaWrapper;
21import org.onosproject.ospf.controller.LsdbAge;
22import org.onosproject.ospf.controller.OspfArea;
23import org.onosproject.ospf.controller.OspfInterface;
24import org.onosproject.ospf.controller.OspfLsaType;
25import org.onosproject.ospf.controller.OspfLsdb;
26import org.onosproject.ospf.controller.area.OspfAreaImpl;
27import org.onosproject.ospf.protocol.lsa.LsaHeader;
28import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
29import org.onosproject.ospf.protocol.util.OspfParameters;
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33import java.util.HashMap;
34import java.util.Iterator;
35import java.util.List;
36import java.util.Map;
37import java.util.concurrent.CopyOnWriteArrayList;
38
39/**
40 * Represents the Link State Database.
41 */
42public class OspfLsdbImpl implements OspfLsdb {
43 private static final Logger log = LoggerFactory.getLogger(OspfLsdbImpl.class);
44 private Map routerLsas = new HashMap();
45 private Map networkLsas = new HashMap();
46 private Map summaryLsas = new HashMap();
47 private Map asbrSummaryLSAs = new HashMap();
48 private Map opaque9Lsas = new HashMap();
49 private Map opaque10Lsas = new HashMap();
50 private Map opaque11Lsas = new HashMap();
51 private Map externalLsas = new HashMap();
52 private long routerLsaSeqNo = OspfParameters.STARTLSSEQUENCENUM;
53 private long networkLsaSeqNo = OspfParameters.STARTLSSEQUENCENUM;
54 private LsdbAge lsdbAge = null;
55 private OspfArea ospfArea = null;
56
57
58 /**
59 * Creates an instance of OSPF LSDB.
60 *
61 * @param ospfArea area instance
62 */
63 public OspfLsdbImpl(OspfArea ospfArea) {
64 this.ospfArea = ospfArea;
65 lsdbAge = new LsdbAgeImpl(ospfArea);
66 }
67
68 @Override
69 public boolean equals(Object o) {
70 if (this == o) {
71 return true;
72 }
73 if (o == null || getClass() != o.getClass()) {
74 return false;
75 }
76 OspfLsdbImpl that = (OspfLsdbImpl) o;
77 return Objects.equal(routerLsas.size(), that.routerLsas.size()) &&
78 Objects.equal(networkLsas.size(), that.networkLsas.size()) &&
79 Objects.equal(summaryLsas.size(), that.summaryLsas.size()) &&
80 Objects.equal(asbrSummaryLSAs.size(), that.asbrSummaryLSAs.size()) &&
81 Objects.equal(lsdbAge, that.lsdbAge) &&
82 Objects.equal(routerLsaSeqNo, that.routerLsaSeqNo) &&
83 Objects.equal(networkLsaSeqNo, that.networkLsaSeqNo);
84 }
85
86 @Override
87 public int hashCode() {
88 return Objects.hashCode(routerLsas, networkLsas, summaryLsas, asbrSummaryLSAs, lsdbAge,
89 routerLsaSeqNo, networkLsaSeqNo);
90 }
91
92 /**
93 * Initializes the link state database.
94 */
95 public void initializeDb() {
96 lsdbAge.startDbAging();
97 }
98
99 /**
100 * Returns all LSA Headers (Router and Summary) in a Vector.
101 *
102 * @param excludeMaxAgeLsa exclude the max age LSAs
103 * @param isOpaqueCapable is opaque capable or not
104 * @return List of LSA headers
105 */
106 public List getAllLsaHeaders(boolean excludeMaxAgeLsa, boolean isOpaqueCapable) {
107 List summList = new CopyOnWriteArrayList();
108 addLsaToHeaderList(summList, excludeMaxAgeLsa, routerLsas);
109 addLsaToHeaderList(summList, excludeMaxAgeLsa, networkLsas);
110 addLsaToHeaderList(summList, excludeMaxAgeLsa, summaryLsas);
111 addLsaToHeaderList(summList, excludeMaxAgeLsa, asbrSummaryLSAs);
112 addLsaToHeaderList(summList, excludeMaxAgeLsa, externalLsas);
113 if (isOpaqueCapable) {
114 addLsaToHeaderList(summList, excludeMaxAgeLsa, opaque9Lsas);
115 addLsaToHeaderList(summList, excludeMaxAgeLsa, opaque10Lsas);
116 addLsaToHeaderList(summList, excludeMaxAgeLsa, opaque11Lsas);
117 }
118
119 return summList;
120 }
121
122 /**
123 * Adds the LSAs to summary list.
124 *
125 * @param summList summary list
126 * @param excludeMaxAgeLsa exclude max age LSA
127 * @param lsaMap map of LSA
128 */
129 private void addLsaToHeaderList(List summList, boolean excludeMaxAgeLsa, Map lsaMap) {
130 Iterator slotVals = lsaMap.values().iterator();
131 while (slotVals.hasNext()) {
132 LsaWrapper wrapper = (LsaWrapper) slotVals.next();
133 if (excludeMaxAgeLsa) {
134 //if current age of lsa is max age or lsa present in Max Age bin
135 if (wrapper.currentAge() != OspfParameters.MAXAGE &&
136 lsdbAge.getMaxAgeBin().ospfLsa(((OspfAreaImpl)
137 ospfArea).getLsaKey(((LsaWrapperImpl) wrapper).lsaHeader())) == null) {
138 addToList(wrapper, summList);
139 }
140 } else {
141 addToList(wrapper, summList);
142 }
143 }
144 }
145
146 /**
147 * Adds the LSWrapper to summary list.
148 *
149 * @param wrapper LSA wrapper instance
150 * @param summList LSA summary list
151 */
152 private void addToList(LsaWrapper wrapper, List summList) {
153 LsaHeader header = (LsaHeader) wrapper.ospfLsa();
154 //set the current age
155 header.setAge(wrapper.currentAge());
156 summList.add(header);
157 }
158
159 /**
160 * Gets the LSDB LSA key from Lsa Header.
161 *
162 * @param lsaHeader LSA header instance
163 * @return key
164 */
165 public String getLsaKey(LsaHeader lsaHeader) {
166 String lsaKey = "";
167 switch (lsaHeader.lsType()) {
168 case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
169 case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
170 case OspfParameters.AS_OPAQUE_LSA:
171 OpaqueLsaHeader header = (OpaqueLsaHeader) lsaHeader;
172 lsaKey = lsaHeader.lsType() + "-" + header.opaqueType() + header.opaqueId() + "-" +
173 lsaHeader.advertisingRouter();
174 break;
175 case OspfParameters.ROUTER:
176 case OspfParameters.NETWORK:
177 case OspfParameters.ASBR_SUMMARY:
178 case OspfParameters.SUMMARY:
179 case OspfParameters.EXTERNAL_LSA:
180 lsaKey = lsaHeader.lsType() + "-" + lsaHeader.linkStateId() + "-" +
181 lsaHeader.advertisingRouter();
182 break;
183 default:
184 log.debug("Unknown LSA type..!!!");
185 break;
186 }
187
188 return lsaKey;
189 }
190
191 /**
192 * Gets wrapper instance in LSDB.
193 *
194 * @param lsaHeader LSA header instance.
195 * @return LSA Wrapper instance.
196 */
197 public LsaWrapper lsaLookup(LsaHeader lsaHeader) {
198
199 return findLsa(lsaHeader.lsType(), getLsaKey(lsaHeader));
200 }
201
202 /**
203 * Finds the LSA from appropriate maps.
204 *
205 * @param lsType type of LSA
206 * @param lsaKey key
207 * @return LSA wrapper object
208 */
209 public LsaWrapper findLsa(int lsType, String lsaKey) {
210 LsaWrapper lsaWrapper = null;
211
212 switch (lsType) {
213 case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
214 lsaWrapper = (LsaWrapper) opaque9Lsas.get(lsaKey);
215 break;
216 case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
217 lsaWrapper = (LsaWrapper) opaque10Lsas.get(lsaKey);
218 break;
219 case OspfParameters.AS_OPAQUE_LSA:
220 lsaWrapper = (LsaWrapper) opaque11Lsas.get(lsaKey);
221 break;
222 case OspfParameters.ROUTER:
223 lsaWrapper = (LsaWrapper) routerLsas.get(lsaKey);
224 break;
225 case OspfParameters.NETWORK:
226 lsaWrapper = (LsaWrapper) networkLsas.get(lsaKey);
227 break;
228 case OspfParameters.ASBR_SUMMARY:
229 lsaWrapper = (LsaWrapper) asbrSummaryLSAs.get(lsaKey);
230 break;
231 case OspfParameters.SUMMARY:
232 lsaWrapper = (LsaWrapper) summaryLsas.get(lsaKey);
233 break;
234 case OspfParameters.EXTERNAL_LSA:
235 lsaWrapper = (LsaWrapper) externalLsas.get(lsaKey);
236 break;
237 default:
238 log.debug("Unknown LSA type..!!!");
239 break;
240 }
241
242 //set the current age
243 if (lsaWrapper != null) {
244 //set the current age
245 ((LsaWrapperImpl) lsaWrapper).lsaHeader().setAge(lsaWrapper.currentAge());
246 ((LsaHeader) lsaWrapper.ospfLsa()).setAge(lsaWrapper.currentAge());
247 }
248
249 return lsaWrapper;
250 }
251
252
253 /**
254 * Installs a new self-originated LSA if possible.
255 * Return true if installing was successful else false.
256 *
257 * @param newLsa LSA header instance
258 * @param isSelfOriginated is self originated or not
259 * @param ospfInterface OSPF interface instance
260 * @return true if successfully added
261 */
262 public boolean addLsa(LsaHeader newLsa, boolean isSelfOriginated, OspfInterface ospfInterface) {
263
264 LsaWrapperImpl lsaWrapper = new LsaWrapperImpl();
265 lsaWrapper.setLsaType(newLsa.getOspfLsaType());
266 lsaWrapper.setOspfLsa(newLsa);
267 lsaWrapper.setLsaHeader(newLsa);
268 lsaWrapper.setLsaAgeReceived(newLsa.age());
269 lsaWrapper.setAgeCounterWhenReceived(lsdbAge.getAgeCounter());
sunishvkf7c56552016-07-18 16:02:39 +0530270 lsaWrapper.setAgeCounterRollOverWhenAdded(lsdbAge.getAgeCounterRollOver());
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530271 lsaWrapper.setIsSelfOriginated(isSelfOriginated);
272 lsaWrapper.setIsSelfOriginated(isSelfOriginated);
273 lsaWrapper.setOspfInterface(ospfInterface);
274 lsaWrapper.setLsdbAge(lsdbAge);
275 addLsa(lsaWrapper);
276
277 log.debug("Added LSA In LSDB: {}", newLsa);
278
279 return true;
280 }
281
282 /**
283 * Installs a new self-originated LSA if possible.
284 * Return true if installing was successful else false.
285 * Adding LSA In cases
286 * 1) New Self Originated LSA based on change in topology
287 * 2) New Self Originated LSA because of LSRefresh
288 * 2) New LSA received via Link State Update Packet
289 *
290 * @param newLsa LSA wrapper instance
291 * @return true if added successfully
292 */
293 private boolean addLsa(LsaWrapper newLsa) {
294 // adding an LSA - verify if it's old or new
295 // verify min failed
296 // to verify if it's a new LSA or updating the old LSA .
297 // fetch the LSA Type
298 // verify if the LSA age is ! Max Age
299 // a) it is received during the flooding process (Section 13)
300 // b) it is originated by the router itself (Section 12.4)
301 // start aging .
302 String key = getLsaKey(((LsaWrapperImpl) newLsa).lsaHeader());
303 //Remove the lsa from bin if exist. we will be adding it in new bin based on the current age.
304 removeLsaFromBin(lsaLookup(((LsaWrapperImpl) newLsa).lsaHeader()));
305
306 switch (((LsaWrapperImpl) newLsa).lsaHeader().lsType()) {
307
308 case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
309 opaque9Lsas.put(key, newLsa);
310 break;
311 case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
312 opaque10Lsas.put(key, newLsa);
313 break;
314 case OspfParameters.AS_OPAQUE_LSA:
315 opaque11Lsas.put(key, newLsa);
316 break;
317 case OspfParameters.ROUTER:
318 routerLsas.put(key, newLsa);
319 break;
320 case OspfParameters.NETWORK:
321 networkLsas.put(key, newLsa);
322 break;
323 case OspfParameters.ASBR_SUMMARY:
324 asbrSummaryLSAs.put(key, newLsa);
325 break;
326 case OspfParameters.SUMMARY:
327 summaryLsas.put(key, newLsa);
328 break;
329 case OspfParameters.EXTERNAL_LSA:
330 externalLsas.put(key, newLsa);
331 break;
332 default:
333 log.debug("Unknown LSA type to add..!!!");
334 break;
335 }
336 //add it to bin
337 Integer binNumber = lsdbAge.age2Bin(((LsaWrapperImpl) newLsa).lsaHeader().age());
338 LsaBin lsaBin = lsdbAge.getLsaBin(binNumber);
339 if (lsaBin != null) {
340 //remove from existing
341 newLsa.setBinNumber(binNumber);
342 lsaBin.addOspfLsa(key, newLsa);
343 lsdbAge.addLsaBin(binNumber, lsaBin);
344 log.debug("Added Type {} LSA to LSDB and LSABin[{}], Age of LSA {}", newLsa.lsaType(),
345 binNumber, ((LsaWrapperImpl) newLsa).lsaHeader().age());
346 }
347
348 return false;
349 }
350
351 /**
352 * Adds the LSA to maxAge bin.
353 *
354 * @param key key
355 * @param wrapper LSA wrapper instance
356 */
357 public void addLsaToMaxAgeBin(String key, Object wrapper) {
358 lsdbAge.addLsaToMaxAgeBin(key, (LsaWrapper) wrapper);
359 }
360
361 /**
362 * Removes LSA from Bin.
363 *
364 * @param lsaWrapper LSA wrapper instance
365 */
366 public void removeLsaFromBin(Object lsaWrapper) {
367 if (lsaWrapper != null) {
368 lsdbAge.removeLsaFromBin((LsaWrapper) lsaWrapper);
369 }
370 }
371
372 /**
373 * RFC 2328 - Section 13.1. Determining which LSA is newer.
374 *
375 * @param lsa1 LSA instance
376 * @param lsa2 LSA instance
377 * @return string status
378 */
379 public String isNewerOrSameLsa(LsaHeader lsa1, LsaHeader lsa2) {
380 if (lsa1.lsSequenceNo() > lsa2.lsSequenceNo()) {
381 return "latest";
382 } else if (lsa1.lsSequenceNo() < lsa2.lsSequenceNo()) {
383 return "old";
384 } else if (lsa1.lsSequenceNo() == lsa2.lsSequenceNo()) {
385 if (lsa1.lsCheckSum() > lsa2.lsCheckSum()) {
386 return "latest";
387 } else if (lsa1.lsCheckSum() < lsa2.lsCheckSum()) {
388 return "old";
389 } else if (lsa1.lsCheckSum() == lsa2.lsCheckSum()) {
390 if (lsa1.age() == lsa2.age()) {
391 return "same";
392 } else if (lsa1.age() == OspfParameters.MAXAGE) {
393 return "latest";
394 } else if (lsa2.age() == OspfParameters.MAXAGE) {
395 return "old";
396 } else if (OspfParameters.MAXAGEDIFF == (lsa1.age() - lsa2.age())) {
397 if (lsa1.age() < lsa2.age()) {
398 return "latest";
399 } else {
400 return "old";
401 }
402 } else {
403 return "same";
404 }
405 }
406 }
407
408 return "";
409 }
410
411 /**
412 * Gets the sequence number.
413 *
414 * @param lsaType type of LSA
415 * @return sequence number
416 */
417 public long getLsSequenceNumber(OspfLsaType lsaType) {
418 switch (lsaType) {
419 case ROUTER:
420 return routerLsaSeqNo++;
421 case NETWORK:
422 return networkLsaSeqNo++;
423 default:
424 return OspfParameters.STARTLSSEQUENCENUM;
425 }
426 }
427
428 /**
429 * Deletes the given LSA.
430 *
431 * @param lsaHeader LSA header instance
432 */
433 public void deleteLsa(LsaHeader lsaHeader) {
434
435 String lsaKey = getLsaKey(lsaHeader);
436 switch (lsaHeader.lsType()) {
437 case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
438 opaque9Lsas.remove(lsaKey);
439 break;
440 case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
441 opaque10Lsas.remove(lsaKey);
442 break;
443 case OspfParameters.AS_OPAQUE_LSA:
444 opaque11Lsas.remove(lsaKey);
445 break;
446 case OspfParameters.ROUTER:
447 routerLsas.remove(lsaKey);
448 break;
449 case OspfParameters.NETWORK:
450 networkLsas.remove(lsaKey);
451 break;
452 case OspfParameters.ASBR_SUMMARY:
453 asbrSummaryLSAs.remove(lsaKey);
454 break;
455 case OspfParameters.SUMMARY:
456 summaryLsas.remove(lsaKey);
457 break;
458 case OspfParameters.EXTERNAL_LSA:
459 externalLsas.remove(lsaKey);
460 break;
461 default:
462 log.debug("Unknown LSA type to delete..!!!");
463 break;
464 }
465 }
466
467 /**
468 * Sets sequence number.
469 *
470 * @param routerLsaSeqNo sequence number
471 */
472 public void setRouterLsaSeqNo(long routerLsaSeqNo) {
473 this.routerLsaSeqNo = routerLsaSeqNo;
474 }
475
476 /**
477 * Sets sequence number.
478 *
479 * @param networkLsaSeqNo sequence number
480 */
481 public void setNetworkLsaSeqNo(long networkLsaSeqNo) {
482 this.networkLsaSeqNo = networkLsaSeqNo;
483 }
484}