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