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