blob: 2c33ed536774f850f0283b22881d853778ac300d [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.area;
17
18import com.fasterxml.jackson.annotation.JsonProperty;
19import com.google.common.base.MoreObjects;
20import com.google.common.base.Objects;
21import org.onlab.packet.Ip4Address;
22import org.onosproject.ospf.controller.LsaWrapper;
23import org.onosproject.ospf.controller.OspfArea;
24import org.onosproject.ospf.controller.OspfAreaAddressRange;
25import org.onosproject.ospf.controller.OspfInterface;
26import org.onosproject.ospf.controller.OspfLsa;
27import org.onosproject.ospf.controller.OspfLsaType;
28import org.onosproject.ospf.controller.OspfLsdb;
29import org.onosproject.ospf.controller.OspfNbr;
30import org.onosproject.ospf.controller.OspfNeighborState;
31import org.onosproject.ospf.controller.impl.OspfNbrImpl;
32import org.onosproject.ospf.controller.lsdb.OspfLsdbImpl;
33import org.onosproject.ospf.protocol.lsa.LsaHeader;
34import org.onosproject.ospf.protocol.lsa.subtypes.OspfLsaLink;
35import org.onosproject.ospf.protocol.lsa.types.NetworkLsa;
36import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
37import org.onosproject.ospf.protocol.util.ChecksumCalculator;
38import org.onosproject.ospf.protocol.util.OspfInterfaceState;
39import org.onosproject.ospf.protocol.util.OspfParameters;
40import org.onosproject.ospf.protocol.util.OspfUtil;
41import org.slf4j.Logger;
42import org.slf4j.LoggerFactory;
43
44import java.net.InetAddress;
45import java.util.ArrayList;
46import java.util.Arrays;
47import java.util.Iterator;
48import java.util.List;
49import java.util.Map;
50
51/**
52 * Representation an OSPF area and related information.
53 */
54public class OspfAreaImpl implements OspfArea {
55 private static final Logger log = LoggerFactory.getLogger(OspfAreaImpl.class);
56 /**
57 * Address ranges in order to aggregate routing information at area.
58 * boundaries. Each address range is specified by an [address,mask] pair and
59 * a status indication of either Advertise or DoNotAdvertise
60 */
61 private List<OspfAreaAddressRange> addressRanges;
62 /**
63 * This parameter indicates whether the area can carry data traffic that.
64 * neither originates nor terminates in the area itself.
65 */
66 private boolean transitCapability;
67 /**
68 * Whether AS-external-LSAs will be flooded into/throughout the area.
69 */
70 private boolean externalRoutingCapability;
71 /**
72 * Indicates the cost of the default summary-LSA.
73 */
74 private int stubCost;
75 /**
76 * Represents a list of all router's interfaces associated with this area.
77 */
78 private List<OspfInterface> interfacesLst;
79 /**
80 * The LS Database for this area. It includes router-LSAs, network-LSAs and.
81 * summary-LSAs. AS-external-LSAs are hold in the OSPF class itself.
82 */
83 private OspfLsdbImpl database;
84 /**
85 * A 32-bit number identifying the area.
86 */
87 private Ip4Address areaId;
88 /**
89 * Router ID.
90 */
91 private Ip4Address routerId;
92 /**
93 * Represents Options like external, opaque capabilities.
94 */
95 private int options;
96 /**
97 * Represents Opaque Enable or not.
98 */
99 private boolean isOpaqueEnable;
100
101 /**
102 * Creates an instance of area implementation.
103 */
104 public OspfAreaImpl() {
105 database = new OspfLsdbImpl(this);
106 }
107
108 @Override
109 public boolean equals(Object o) {
110 if (this == o) {
111 return true;
112 }
113 if (o == null || getClass() != o.getClass()) {
114 return false;
115 }
116 OspfAreaImpl that = (OspfAreaImpl) o;
117 return Objects.equal(areaId, that.areaId) &&
118 Objects.equal(routerId, that.routerId) &&
119 Objects.equal(addressRanges.size(), that.addressRanges.size()) &&
120 Objects.equal(transitCapability, that.transitCapability) &&
121 Objects.equal(externalRoutingCapability, that.externalRoutingCapability) &&
122 Objects.equal(stubCost, that.stubCost) &&
123 Objects.equal(interfacesLst.size(), that.interfacesLst.size()) &&
124 Objects.equal(database, that.database);
125 }
126
127 @Override
128 public int hashCode() {
129 return Objects.hashCode(areaId, routerId, addressRanges, transitCapability, externalRoutingCapability,
130 stubCost, interfacesLst, database);
131 }
132
133 /**
134 * Gets the router id.
135 *
136 * @return router id
137 */
138 public Ip4Address routerId() {
139 return routerId;
140 }
141
142 /**
143 * Sets the router id.
144 *
145 * @param routerId router id
146 */
147 @JsonProperty("routerId")
148 public void setRouterId(Ip4Address routerId) {
149 this.routerId = routerId;
150 }
151
152 /**
153 * Sets opaque enabled to true or false.
154 *
155 * @param isOpaqueEnable true if opaque enabled else false
156 */
157 @JsonProperty("isOpaqueEnable")
158 public void setIsOpaqueEnabled(boolean isOpaqueEnable) {
159 this.isOpaqueEnable = isOpaqueEnable;
160 }
161
162 /**
163 * Gets is opaque enabled or not.
164 *
165 * @return true if opaque enabled else false
166 */
167 public boolean isOpaqueEnabled() {
168 return this.isOpaqueEnable;
169 }
170
171 /**
172 * Initializes link state database.
173 */
174 public void initializeDb() {
175
176 database.initializeDb();
177 }
178
179 /**
180 * Refreshes the OSPF area information .
181 * Gets called as soon as the interface is down or neighbor full Router LSA is updated.
182 *
183 * @param ospfInterface OSPF interface instance
184 */
185 @Override
186 public void refreshArea(OspfInterface ospfInterface) {
187 OspfInterfaceImpl ospfInterfaceImpl = (OspfInterfaceImpl) ospfInterface;
188 log.debug("Inside refreshArea...!!!");
189 //If interface state is DR build network LSA.
190 if (ospfInterfaceImpl.state() == OspfInterfaceState.DR) {
191 if (ospfInterface.listOfNeighbors().size() > 0) {
192 //Get the NetworkLsa
193 NetworkLsa networkLsa = null;
194 try {
195 networkLsa = buildNetworkLsa(ospfInterface.ipAddress(), ospfInterface.ipNetworkMask());
196 } catch (Exception e) {
197 log.debug("Error while building NetworkLsa {}", e.getMessage());
198 }
199 //Add the NetworkLsa to lsdb
200 database.addLsa(networkLsa, true, ospfInterface);
201 addToOtherNeighborLsaTxList(networkLsa);
202 } else {
203 log.debug("No Neighbors hence not creating NetworkLSA...!!!");
204 }
205 }
206 //Get the router LSA
207 RouterLsa routerLsa = null;
208 try {
209 routerLsa = buildRouterLsa(ospfInterface);
210 } catch (Exception e) {
211 log.debug("Error while building RouterLsa {}", e.getMessage());
212 }
213 //Add the RouterLSA to lsdb
214 database.addLsa(routerLsa, true, ospfInterface);
215 addToOtherNeighborLsaTxList(routerLsa);
216 }
217
218 /**
219 * Builds a network LSA.
220 *
221 * @param interfaceIp interface IP address
222 * @param mask interface network mask
223 * @return NetworkLsa instance
224 * @throws Exception might throws exception
225 */
226 public NetworkLsa buildNetworkLsa(Ip4Address interfaceIp, Ip4Address mask) throws Exception {
227 // generate the Router-LSA for this Area.
228 NetworkLsa networkLsa = new NetworkLsa();
229 networkLsa.setAdvertisingRouter(routerId);
230 networkLsa.setLinkStateId(interfaceIp.toString());
231 networkLsa.setLsType(OspfLsaType.NETWORK.value());
232 networkLsa.setAge(1);
233 networkLsa.setOptions(2);
234 networkLsa.setNetworkMask(mask);
235 //Adding our own router.
236 networkLsa.addAttachedRouter(routerId());
237 Iterator iter = interfacesLst.iterator();
238 OspfInterfaceImpl ospfInterface = null;
239 while (iter.hasNext()) {
240 ospfInterface = (OspfInterfaceImpl) iter.next();
241 if (ospfInterface.ipAddress().equals(interfaceIp)) {
242 break;
243 }
244 }
245 if (ospfInterface != null) {
246 List<OspfNbr> neighborsInFullState = getNeighborsInFullState(ospfInterface);
247 if (neighborsInFullState != null) {
248 for (OspfNbr ospfnbr : neighborsInFullState) {
249 networkLsa.addAttachedRouter(ospfnbr.neighborId());
250 log.debug("Adding attached neighbor:: {}", ospfnbr.neighborId());
251 }
252 }
253 }
254 networkLsa.setLsSequenceNo(database.getLsSequenceNumber(OspfLsaType.NETWORK));
255 //Find the byte length and add it in lsa object
256 ChecksumCalculator checksum = new ChecksumCalculator();
257 byte[] lsaBytes = networkLsa.asBytes();
258 networkLsa.setLsPacketLen(lsaBytes.length);
259 //Convert lsa object to byte again to reflect the packet length which we added.
260 lsaBytes = networkLsa.asBytes();
261 //find the checksum
262 byte[] twoByteChecksum = checksum.calculateLsaChecksum(lsaBytes,
263 OspfUtil.LSAPACKET_CHECKSUM_POS1,
264 OspfUtil.LSAPACKET_CHECKSUM_POS2);
265 int checkSumVal = OspfUtil.byteToInteger(twoByteChecksum);
266 networkLsa.setLsCheckSum(checkSumVal);
267 return networkLsa;
268 }
269
270 /**
271 * Builds Router LSA.
272 *
273 * @param ospfInterface Interface instance
274 * @return routerLsa Router LSA instance
275 * @throws Exception might throws exception
276 */
277 public RouterLsa buildRouterLsa(OspfInterface ospfInterface) throws Exception {
278 // generate the Router-LSA for this Area.
279 RouterLsa routerLsa = new RouterLsa();
280 routerLsa.setAdvertisingRouter(routerId);
281 routerLsa.setLinkStateId(routerId.toString());
282 routerLsa.setLsType(OspfLsaType.ROUTER.value());
283 routerLsa.setAge(1);
284 routerLsa.setOptions(options);
285 routerLsa.setAreaBorderRouter(false);
286 routerLsa.setAsBoundaryRouter(false);
287 routerLsa.setVirtualEndPoint(false);
288 buildLinkForRouterLsa(routerLsa, ospfInterface);
289 routerLsa.setLsSequenceNo(database.getLsSequenceNumber(OspfLsaType.ROUTER));
290 //Find the byte length and add it in lsa object
291 ChecksumCalculator checksum = new ChecksumCalculator();
292 byte[] lsaBytes = routerLsa.asBytes();
293 routerLsa.setLsPacketLen(lsaBytes.length);
294 //Convert lsa object to byte again to reflect the packet length whic we added.
295 lsaBytes = routerLsa.asBytes();
296 //find the checksum
297 byte[] twoByteChecksum = checksum.calculateLsaChecksum(lsaBytes,
298 OspfUtil.LSAPACKET_CHECKSUM_POS1,
299 OspfUtil.LSAPACKET_CHECKSUM_POS2);
300 int checkSumVal = OspfUtil.byteToInteger(twoByteChecksum);
301 routerLsa.setLsCheckSum(checkSumVal);
302 return routerLsa;
303 }
304
305 /**
306 * Builds LSA link for router LSA.
307 *
308 * @param routerLsa router LSA instance
309 * @param ospfInterface interface instance
310 */
311 private void buildLinkForRouterLsa(RouterLsa routerLsa, OspfInterface ospfInterface) {
312 OspfInterfaceImpl nextInterface;
313 Iterator interfaces = interfacesLst.iterator();
314 while (interfaces.hasNext()) {
315 nextInterface = (OspfInterfaceImpl) interfaces.next();
316 if (nextInterface.state() == OspfInterfaceState.DOWN) {
317 continue;
318 } else if (nextInterface.state() == OspfInterfaceState.LOOPBACK) {
319 OspfLsaLink link = new OspfLsaLink();
320 link.setLinkData("-1");
321 link.setLinkId(nextInterface.ipAddress().toString());
322 link.setLinkType(3);
323 link.setMetric(0);
324 link.setTos(0);
325 routerLsa.addRouterLink(link);
326 routerLsa.incrementLinkNo();
327 } else if (nextInterface.state() == OspfInterfaceState.POINT2POINT) {
328 // adding all neighbour routers
329 List<OspfNbr> neighborsInFullState = getNeighborsInFullState(nextInterface);
330 if (neighborsInFullState != null) {
331 log.debug("Adding OspfLsaLink ::neighborsInFullState {}, InterfaceIP: {}",
332 neighborsInFullState.size(), nextInterface.ipAddress());
333 for (OspfNbr ospfnbr : neighborsInFullState) {
334 OspfLsaLink link = new OspfLsaLink();
335 link.setLinkData(nextInterface.ipAddress().toString());
336 link.setLinkId(ospfnbr.neighborId().toString());
337 link.setLinkType(1);
338 link.setMetric(0);
339 link.setTos(0);
340 routerLsa.addRouterLink(link);
341 routerLsa.incrementLinkNo();
342 log.debug("Added OspfLsaLink :: {}, neighborIP: {}, routerLinks: {}",
343 ospfnbr.neighborId(), ospfnbr.neighborIpAddr(), routerLsa.noLink());
344 }
345 }
346 // adding the self address
347 OspfLsaLink link = new OspfLsaLink();
348 link.setLinkData(nextInterface.ipNetworkMask().toString());
349 link.setLinkId(nextInterface.ipAddress().toString());
350 link.setLinkType(3);
351 link.setMetric(0);
352 link.setTos(0);
353 routerLsa.addRouterLink(link);
354 routerLsa.incrementLinkNo();
355 } else {
356 buildLinkForRouterLsaBroadcast(routerLsa, nextInterface);
357 }
358 }
359 }
360
361 /**
362 * Builds LSA link for router LSA.
363 *
364 * @param routerLsa router LSA instance
365 * @param ospfInterface interface instance
366 */
367 private void buildLinkForRouterLsaBroadcast(RouterLsa routerLsa, OspfInterface ospfInterface) {
368 OspfInterfaceImpl ospfInterfaceImpl = (OspfInterfaceImpl) ospfInterface;
369 if (ospfInterfaceImpl.state() == OspfInterfaceState.WAITING) {
370 OspfLsaLink link = new OspfLsaLink();
371 link.setLinkData(ospfInterface.ipNetworkMask().toString());
372 //Link id should be set to ip network number
373 link.setLinkId(ospfInterface.ipAddress().toString());
374 link.setLinkType(3);
375 link.setMetric(0);
376 link.setTos(0);
377 routerLsa.addRouterLink(link);
378 routerLsa.incrementLinkNo();
379 } else if (ospfInterfaceImpl.state() == OspfInterfaceState.DR) {
380 OspfLsaLink link = new OspfLsaLink();
381 link.setLinkData(ospfInterface.ipAddress().toString());
382 link.setLinkId(ospfInterface.ipAddress().toString());
383 link.setLinkType(2);
384 link.setMetric(0);
385 link.setTos(0);
386 routerLsa.addRouterLink(link);
387 routerLsa.incrementLinkNo();
388 } else if (ospfInterfaceImpl.state() == OspfInterfaceState.BDR ||
389 ospfInterfaceImpl.state() == OspfInterfaceState.DROTHER) {
390 OspfLsaLink link = new OspfLsaLink();
391 link.setLinkData(ospfInterface.ipAddress().toString());
392 link.setLinkId(ospfInterface.dr().toString());
393 link.setLinkType(2);
394 link.setMetric(0);
395 link.setTos(0);
396 routerLsa.addRouterLink(link);
397 routerLsa.incrementLinkNo();
398 }
399 }
400
401 /**
402 * Gets the area id.
403 *
404 * @return area id
405 */
406 public Ip4Address areaId() {
407 return areaId;
408 }
409
410 /**
411 * Sets the area id.
412 *
413 * @param areaId area id
414 */
415 @JsonProperty("areaId")
416 public void setAreaId(Ip4Address areaId) {
417 this.areaId = areaId;
418 }
419
420 /**
421 * Gets address range.
422 *
423 * @return list of area address ranges
424 */
425 public List<OspfAreaAddressRange> addressRanges() {
426 return addressRanges;
427 }
428
429 /**
430 * Sets the area address ranges.
431 *
432 * @param addressRanges list of area address range
433 */
434 @JsonProperty("addressRange")
435 public void setAddressRanges(List<OspfAreaAddressRange> addressRanges) {
436 this.addressRanges = addressRanges;
437 }
438
439 /**
440 * Gets is transit capable or not.
441 *
442 * @return true if transit capable, else false
443 */
444 public boolean isTransitCapability() {
445 return transitCapability;
446 }
447
448 /**
449 * Sets transit capability.
450 *
451 * @param transitCapability true if transit capable, else false
452 */
453 @JsonProperty("transitCapability")
454 public void setTransitCapability(boolean transitCapability) {
455 this.transitCapability = transitCapability;
456 }
457
458 /**
459 * Gets external routing capability.
460 *
461 * @return true if external routing capable, else false
462 */
463 public boolean isExternalRoutingCapability() {
464 return externalRoutingCapability;
465 }
466
467 /**
468 * Sets external routing capability.
469 *
470 * @param externalRoutingCapability true if external routing capable, else false
471 */
472 @JsonProperty("externalRoutingCapability")
473 public void setExternalRoutingCapability(boolean externalRoutingCapability) {
474 this.externalRoutingCapability = externalRoutingCapability;
475 }
476
477 /**
478 * Gets the stub cost.
479 *
480 * @return stub cost
481 */
482 public int stubCost() {
483 return stubCost;
484 }
485
486 /**
487 * Sets the stub cost.
488 *
489 * @param stubCost stub cost
490 */
491 @JsonProperty("stubCost")
492 public void setStubCost(int stubCost) {
493 this.stubCost = stubCost;
494 }
495
496 /**
497 * Gets the list of interfaces in this area.
498 *
499 * @return list of interfaces
500 */
501 public List<OspfInterface> getInterfacesLst() {
502 return interfacesLst;
503 }
504
505 /**
506 * Sets the list of interfaces attached to the area.
507 *
508 * @param interfacesLst list of OspfInterface instances
509 */
510 @JsonProperty("interface")
511 public void setInterfacesLst(List<OspfInterface> interfacesLst) {
512 this.interfacesLst = interfacesLst;
513 }
514
515 /**
516 * Checks all neighbors belonging to this area whether they are in state EXCHANGE or LOADING.
517 * Return false if there is at least one, else return true. This Method is used by
518 * "processReceivedLsa()" in the neighbor class.
519 *
520 * @return boolean indicating that there is no Neighbor in Database Exchange
521 */
522 public boolean noNeighborInLsaExchangeProcess() {
523 OspfInterfaceImpl nextInterface;
524 OspfNeighborState nextNeighborState;
525 Iterator interfaces = interfacesLst.iterator();
526 while (interfaces.hasNext()) {
527 nextInterface = (OspfInterfaceImpl) interfaces.next();
528 Iterator neighbors = nextInterface.listOfNeighbors().values().iterator();
529 while (neighbors.hasNext()) {
530 nextNeighborState = ((OspfNbrImpl) neighbors.next()).getState();
531 if (nextNeighborState == OspfNeighborState.EXCHANGE ||
532 nextNeighborState == OspfNeighborState.LOADING) {
533 return false;
534 }
535 }
536 }
537 return true;
538 }
539
540 /**
541 * Gets header of all types of LSAs.
542 *
543 * @param excludeMaxAgeLsa need to include(true) or exclude(false) maxage lsa's
544 * @param isOpaquecapable need to include(true) or exclude(false) Type 10 Opaque lsa's
545 * @return list of lsa header in the lsdb
546 */
547 public List getLsaHeaders(boolean excludeMaxAgeLsa, boolean isOpaquecapable) {
548 return database.getAllLsaHeaders(excludeMaxAgeLsa, isOpaquecapable);
549 }
550
551 /**
552 * Gets the LSA from LSDB based on the input.
553 *
554 * @param lsType type of lsa to form the key
555 * @param linkStateID link state id to form the key
556 * @param advertisingRouter advertising router to form the key
557 * @return lsa wrapper instance which contains the Lsa
558 * @throws Exception might throws exception
559 */
560 public LsaWrapper getLsa(int lsType, String linkStateID, String advertisingRouter) throws Exception {
561 String lsaKey = lsType + "-" + linkStateID + "-" + advertisingRouter;
562 if (lsType == OspfParameters.LINK_LOCAL_OPAQUE_LSA || lsType == OspfParameters.AREA_LOCAL_OPAQUE_LSA ||
563 lsType == OspfParameters.AS_OPAQUE_LSA) {
564 byte[] linkStateAsBytes = InetAddress.getByName(linkStateID).getAddress();
565 int opaqueType = linkStateAsBytes[0];
566 int opaqueId = OspfUtil.byteToInteger(Arrays.copyOfRange(linkStateAsBytes, 1,
567 linkStateAsBytes.length));
568 lsaKey = lsType + "-" + opaqueType + opaqueId + "-" + advertisingRouter;
569 }
570 return database.findLsa(lsType, lsaKey);
571 }
572
573
574 /**
575 * Checks whether an instance of the given LSA exists in the database belonging to this area.
576 * If so return true else false.
577 *
578 * @param lookupLsa ospf LSA instance to lookup
579 * @return LSA wrapper instance which contains the Lsa
580 */
581 public LsaWrapper lsaLookup(OspfLsa lookupLsa) {
582 return database.lsaLookup((LsaHeader) lookupLsa);
583 }
584
585 /**
586 * Checks whether an instance of the given LSA exists in the database belonging to this area.
587 * If so return true else false.
588 *
589 * @param lsa1 OSPF LSA instance to compare
590 * @param lsa2 OSPF LSA instance to compare
591 * @return "same" if both instances are same, "latest" if lsa1 is latest, or "old" if lsa1 is old
592 */
593 public String isNewerOrSameLsa(OspfLsa lsa1, OspfLsa lsa2) {
594 return database.isNewerOrSameLsa((LsaHeader) lsa1, (LsaHeader) lsa2);
595 }
596
597 /**
598 * Methods gets called from ChannelHandler to add the received LSA to LSDB.
599 *
600 * @param ospfLsa OSPF LSA instance
601 * @param ospfInterface OSPF interface instance
602 */
603 public void addLsa(OspfLsa ospfLsa, OspfInterface ospfInterface) throws Exception {
604 //second param is false as lsa from network
605 database.addLsa((LsaHeader) ospfLsa, false, ospfInterface);
606 }
607
608 /**
609 * Methods gets called from ChannelHandler to add the received LSA to LSDB.
610 *
611 * @param ospfLsa OSPF LSA instance
612 * @param isSelfOriginated true if the LSA is self originated. Else false
613 * @param ospfInterface OSPF interface instance
614 */
615 public void addLsa(OspfLsa ospfLsa, boolean isSelfOriginated, OspfInterface ospfInterface)
616 throws Exception {
617 database.addLsa((LsaHeader) ospfLsa, isSelfOriginated, ospfInterface);
618 }
619
620 /**
621 * Adds the LSA to maxAge bin.
622 *
623 * @param key key to add it to LSDB
624 * @param wrapper LSA wrapper instance
625 */
626 public void addLsaToMaxAgeBin(String key, LsaWrapper wrapper) {
627 database.addLsaToMaxAgeBin(key, wrapper);
628 }
629
630 /**
631 * Sets router sequence number for router LSA.
632 *
633 * @param newSequenceNumber sequence number
634 */
635 public void setDbRouterSequenceNumber(long newSequenceNumber) {
636 database.setRouterLsaSeqNo(newSequenceNumber);
637 }
638
639 /**
640 * Methods gets called from ChannelHandler to delete the LSA.
641 *
642 * @param ospfLsa the LSA instance to delete
643 */
644 public void deleteLsa(LsaHeader ospfLsa) {
645 database.deleteLsa(ospfLsa);
646 }
647
648 /**
649 * Removes LSA from bin.
650 *
651 * @param lsaWrapper the LSA wrapper instance to delete
652 */
653 public void removeLsaFromBin(LsaWrapper lsaWrapper) {
654 database.removeLsaFromBin(lsaWrapper);
655 }
656
657 @Override
658 public String toString() {
659 return MoreObjects.toStringHelper(getClass())
660 .omitNullValues()
661 .add("areaID", areaId)
662 .add("stubCost", stubCost)
663 .add("addressRanges", addressRanges)
664 .add("interfacesLst", interfacesLst)
665 .add("transitCapability", transitCapability)
666 .add("externalRoutingCapability", externalRoutingCapability)
667 .toString();
668 }
669
670 /**
671 * Checks all Neighbors belonging to this Area whether they are in state lesser than the EXCHANGE.
672 * <p>
673 * Creates list of such neighbors
674 * <p>
675 * Returns list of neighbors who satisfy the conditions
676 *
677 * @param ospfInterface OSPF interface instance
678 * @return List of interfaces having state lesser than exchange
679 */
680 public List<OspfNbr> getNeighborsInFullState(OspfInterface ospfInterface) {
681
682 List<OspfNbr> listEligibleNeighbors = null;
683 OspfNbrImpl ospfNeighbor = null;
684 OspfNeighborState nextNeighborState;
685 Iterator nbrInterface = ospfInterface.listOfNeighbors().values().iterator();
686 while (nbrInterface.hasNext()) {
687 ospfNeighbor = (OspfNbrImpl) nbrInterface.next();
688 nextNeighborState = ospfNeighbor.getState();
689 if (nextNeighborState.getValue() == OspfNeighborState.FULL.getValue()) {
690 if (listEligibleNeighbors == null) {
691 listEligibleNeighbors = new ArrayList<OspfNbr>();
692 listEligibleNeighbors.add(ospfNeighbor);
693 } else {
694 listEligibleNeighbors.add(ospfNeighbor);
695 }
696 }
697 }
698 return listEligibleNeighbors;
699 }
700
701 /**
702 * Gets the LSDB LSA key from LSA header.
703 *
704 * @param lsaHeader LSA header instance
705 * @return key LSA key
706 */
707 public String getLsaKey(LsaHeader lsaHeader) {
708 return database.getLsaKey(lsaHeader);
709 }
710
711 /**
712 * Adds the received LSA in other neighbors tx list.
713 *
714 * @param recLsa LSA Header instance
715 */
716 public void addToOtherNeighborLsaTxList(LsaHeader recLsa) {
717 //Add the received LSA in other neighbors retransmission list.
718 log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList");
719 List<OspfInterface> ospfInterfaces = getInterfacesLst();
720 for (OspfInterface ospfInterfaceFromArea : ospfInterfaces) {
721 Map neighbors = ospfInterfaceFromArea.listOfNeighbors();
722 for (Object neighborIP : neighbors.keySet()) {
723 OspfNbrImpl nbr = (OspfNbrImpl) neighbors.get(neighborIP);
724 if (nbr.getState().getValue() < OspfNeighborState.EXCHANGE.getValue()) {
725 continue;
726 }
727 String key = database.getLsaKey(recLsa);
728 if (nbr.getState() == OspfNeighborState.EXCHANGE || nbr.getState() == OspfNeighborState.LOADING) {
729 if (nbr.getLsReqList().containsKey(key)) {
730 LsaWrapper lsWrapper = lsaLookup(recLsa);
731 if (lsWrapper != null) {
732 LsaHeader ownLSA = (LsaHeader) lsWrapper.ospfLsa();
733 String status = isNewerOrSameLsa(recLsa, ownLSA);
734 if (status.equals("old")) {
735 continue;
736 } else if (status.equals("same")) {
737 log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: " +
738 "Removing lsa from reTxtList {}", key);
739 nbr.getLsReqList().remove(key);
740 continue;
741 } else {
742 log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: " +
743 "Removing lsa from reTxtList {}", key);
744 nbr.getLsReqList().remove(key);
745 }
746 }
747 }
748 }
749 if (recLsa.advertisingRouter().equals((String) neighborIP)) {
750 continue;
751 }
752 if ((recLsa.lsType() == OspfParameters.LINK_LOCAL_OPAQUE_LSA ||
753 recLsa.lsType() == OspfParameters.AREA_LOCAL_OPAQUE_LSA)) {
754 if (nbr.isOpaqueCapable()) {
755 log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: Adding lsa to reTxtList {}",
756 recLsa);
757 nbr.getReTxList().put(key, recLsa);
758 }
759 } else {
760 log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: Adding lsa to reTxtList {}",
761 recLsa);
762 nbr.getReTxList().put(key, recLsa);
763 }
764 }
765 }
766 }
767
768 /**
769 * Gets the options value.
770 *
771 * @return options value
772 */
773 public int options() {
774 return options;
775 }
776
777 /**
778 * Sets the options value.
779 *
780 * @param options options value
781 */
782 public void setOptions(int options) {
783 this.options = options;
784 }
785
786 /**
787 * Gets the opaque enabled options value.
788 *
789 * @return opaque enabled options value
790 */
791 public int opaqueEnabledOptions() {
792 return Integer.parseInt(OspfParameters.OPAQUE_ENABLED_OPTION_VALUE, 2);
793 }
794
795 /**
796 * Gets the lsdb instance for this area.
797 *
798 * @return lsdb instance
799 */
800 public OspfLsdb database() {
801 return database;
802 }
803}