blob: 2c30155db323664904e8f115bdfbc58323d9c2e1 [file] [log] [blame]
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301/*
2 * Copyright 2016 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.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());
270 lsaWrapper.setIsSelfOriginated(isSelfOriginated);
271 lsaWrapper.setIsSelfOriginated(isSelfOriginated);
272 lsaWrapper.setOspfInterface(ospfInterface);
273 lsaWrapper.setLsdbAge(lsdbAge);
274 addLsa(lsaWrapper);
275
276 log.debug("Added LSA In LSDB: {}", newLsa);
277
278 return true;
279 }
280
281 /**
282 * Installs a new self-originated LSA if possible.
283 * Return true if installing was successful else false.
284 * Adding LSA In cases
285 * 1) New Self Originated LSA based on change in topology
286 * 2) New Self Originated LSA because of LSRefresh
287 * 2) New LSA received via Link State Update Packet
288 *
289 * @param newLsa LSA wrapper instance
290 * @return true if added successfully
291 */
292 private boolean addLsa(LsaWrapper newLsa) {
293 // adding an LSA - verify if it's old or new
294 // verify min failed
295 // to verify if it's a new LSA or updating the old LSA .
296 // fetch the LSA Type
297 // verify if the LSA age is ! Max Age
298 // a) it is received during the flooding process (Section 13)
299 // b) it is originated by the router itself (Section 12.4)
300 // start aging .
301 String key = getLsaKey(((LsaWrapperImpl) newLsa).lsaHeader());
302 //Remove the lsa from bin if exist. we will be adding it in new bin based on the current age.
303 removeLsaFromBin(lsaLookup(((LsaWrapperImpl) newLsa).lsaHeader()));
304
305 switch (((LsaWrapperImpl) newLsa).lsaHeader().lsType()) {
306
307 case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
308 opaque9Lsas.put(key, newLsa);
309 break;
310 case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
311 opaque10Lsas.put(key, newLsa);
312 break;
313 case OspfParameters.AS_OPAQUE_LSA:
314 opaque11Lsas.put(key, newLsa);
315 break;
316 case OspfParameters.ROUTER:
317 routerLsas.put(key, newLsa);
318 break;
319 case OspfParameters.NETWORK:
320 networkLsas.put(key, newLsa);
321 break;
322 case OspfParameters.ASBR_SUMMARY:
323 asbrSummaryLSAs.put(key, newLsa);
324 break;
325 case OspfParameters.SUMMARY:
326 summaryLsas.put(key, newLsa);
327 break;
328 case OspfParameters.EXTERNAL_LSA:
329 externalLsas.put(key, newLsa);
330 break;
331 default:
332 log.debug("Unknown LSA type to add..!!!");
333 break;
334 }
335 //add it to bin
336 Integer binNumber = lsdbAge.age2Bin(((LsaWrapperImpl) newLsa).lsaHeader().age());
337 LsaBin lsaBin = lsdbAge.getLsaBin(binNumber);
338 if (lsaBin != null) {
339 //remove from existing
340 newLsa.setBinNumber(binNumber);
341 lsaBin.addOspfLsa(key, newLsa);
342 lsdbAge.addLsaBin(binNumber, lsaBin);
343 log.debug("Added Type {} LSA to LSDB and LSABin[{}], Age of LSA {}", newLsa.lsaType(),
344 binNumber, ((LsaWrapperImpl) newLsa).lsaHeader().age());
345 }
346
347 return false;
348 }
349
350 /**
351 * Adds the LSA to maxAge bin.
352 *
353 * @param key key
354 * @param wrapper LSA wrapper instance
355 */
356 public void addLsaToMaxAgeBin(String key, Object wrapper) {
357 lsdbAge.addLsaToMaxAgeBin(key, (LsaWrapper) wrapper);
358 }
359
360 /**
361 * Removes LSA from Bin.
362 *
363 * @param lsaWrapper LSA wrapper instance
364 */
365 public void removeLsaFromBin(Object lsaWrapper) {
366 if (lsaWrapper != null) {
367 lsdbAge.removeLsaFromBin((LsaWrapper) lsaWrapper);
368 }
369 }
370
371 /**
372 * RFC 2328 - Section 13.1. Determining which LSA is newer.
373 *
374 * @param lsa1 LSA instance
375 * @param lsa2 LSA instance
376 * @return string status
377 */
378 public String isNewerOrSameLsa(LsaHeader lsa1, LsaHeader lsa2) {
379 if (lsa1.lsSequenceNo() > lsa2.lsSequenceNo()) {
380 return "latest";
381 } else if (lsa1.lsSequenceNo() < lsa2.lsSequenceNo()) {
382 return "old";
383 } else if (lsa1.lsSequenceNo() == lsa2.lsSequenceNo()) {
384 if (lsa1.lsCheckSum() > lsa2.lsCheckSum()) {
385 return "latest";
386 } else if (lsa1.lsCheckSum() < lsa2.lsCheckSum()) {
387 return "old";
388 } else if (lsa1.lsCheckSum() == lsa2.lsCheckSum()) {
389 if (lsa1.age() == lsa2.age()) {
390 return "same";
391 } else if (lsa1.age() == OspfParameters.MAXAGE) {
392 return "latest";
393 } else if (lsa2.age() == OspfParameters.MAXAGE) {
394 return "old";
395 } else if (OspfParameters.MAXAGEDIFF == (lsa1.age() - lsa2.age())) {
396 if (lsa1.age() < lsa2.age()) {
397 return "latest";
398 } else {
399 return "old";
400 }
401 } else {
402 return "same";
403 }
404 }
405 }
406
407 return "";
408 }
409
410 /**
411 * Gets the sequence number.
412 *
413 * @param lsaType type of LSA
414 * @return sequence number
415 */
416 public long getLsSequenceNumber(OspfLsaType lsaType) {
417 switch (lsaType) {
418 case ROUTER:
419 return routerLsaSeqNo++;
420 case NETWORK:
421 return networkLsaSeqNo++;
422 default:
423 return OspfParameters.STARTLSSEQUENCENUM;
424 }
425 }
426
427 /**
428 * Deletes the given LSA.
429 *
430 * @param lsaHeader LSA header instance
431 */
432 public void deleteLsa(LsaHeader lsaHeader) {
433
434 String lsaKey = getLsaKey(lsaHeader);
435 switch (lsaHeader.lsType()) {
436 case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
437 opaque9Lsas.remove(lsaKey);
438 break;
439 case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
440 opaque10Lsas.remove(lsaKey);
441 break;
442 case OspfParameters.AS_OPAQUE_LSA:
443 opaque11Lsas.remove(lsaKey);
444 break;
445 case OspfParameters.ROUTER:
446 routerLsas.remove(lsaKey);
447 break;
448 case OspfParameters.NETWORK:
449 networkLsas.remove(lsaKey);
450 break;
451 case OspfParameters.ASBR_SUMMARY:
452 asbrSummaryLSAs.remove(lsaKey);
453 break;
454 case OspfParameters.SUMMARY:
455 summaryLsas.remove(lsaKey);
456 break;
457 case OspfParameters.EXTERNAL_LSA:
458 externalLsas.remove(lsaKey);
459 break;
460 default:
461 log.debug("Unknown LSA type to delete..!!!");
462 break;
463 }
464 }
465
466 /**
467 * Sets sequence number.
468 *
469 * @param routerLsaSeqNo sequence number
470 */
471 public void setRouterLsaSeqNo(long routerLsaSeqNo) {
472 this.routerLsaSeqNo = routerLsaSeqNo;
473 }
474
475 /**
476 * Sets sequence number.
477 *
478 * @param networkLsaSeqNo sequence number
479 */
480 public void setNetworkLsaSeqNo(long networkLsaSeqNo) {
481 this.networkLsaSeqNo = networkLsaSeqNo;
482 }
483}