ONOS-2740,ONOS-2741,from ONOS-3032 - to ONOS 3071 , OSPF Protocol Implementation
Change-Id: I592453c21440afa5240c74dc4e9e134f876c89b3
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java
new file mode 100755
index 0000000..2c33ed5
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java
@@ -0,0 +1,803 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ospf.controller.area;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.ospf.controller.LsaWrapper;
+import org.onosproject.ospf.controller.OspfArea;
+import org.onosproject.ospf.controller.OspfAreaAddressRange;
+import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfLsa;
+import org.onosproject.ospf.controller.OspfLsaType;
+import org.onosproject.ospf.controller.OspfLsdb;
+import org.onosproject.ospf.controller.OspfNbr;
+import org.onosproject.ospf.controller.OspfNeighborState;
+import org.onosproject.ospf.controller.impl.OspfNbrImpl;
+import org.onosproject.ospf.controller.lsdb.OspfLsdbImpl;
+import org.onosproject.ospf.protocol.lsa.LsaHeader;
+import org.onosproject.ospf.protocol.lsa.subtypes.OspfLsaLink;
+import org.onosproject.ospf.protocol.lsa.types.NetworkLsa;
+import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
+import org.onosproject.ospf.protocol.util.ChecksumCalculator;
+import org.onosproject.ospf.protocol.util.OspfInterfaceState;
+import org.onosproject.ospf.protocol.util.OspfParameters;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Representation an OSPF area and related information.
+ */
+public class OspfAreaImpl implements OspfArea {
+ private static final Logger log = LoggerFactory.getLogger(OspfAreaImpl.class);
+ /**
+ * Address ranges in order to aggregate routing information at area.
+ * boundaries. Each address range is specified by an [address,mask] pair and
+ * a status indication of either Advertise or DoNotAdvertise
+ */
+ private List<OspfAreaAddressRange> addressRanges;
+ /**
+ * This parameter indicates whether the area can carry data traffic that.
+ * neither originates nor terminates in the area itself.
+ */
+ private boolean transitCapability;
+ /**
+ * Whether AS-external-LSAs will be flooded into/throughout the area.
+ */
+ private boolean externalRoutingCapability;
+ /**
+ * Indicates the cost of the default summary-LSA.
+ */
+ private int stubCost;
+ /**
+ * Represents a list of all router's interfaces associated with this area.
+ */
+ private List<OspfInterface> interfacesLst;
+ /**
+ * The LS Database for this area. It includes router-LSAs, network-LSAs and.
+ * summary-LSAs. AS-external-LSAs are hold in the OSPF class itself.
+ */
+ private OspfLsdbImpl database;
+ /**
+ * A 32-bit number identifying the area.
+ */
+ private Ip4Address areaId;
+ /**
+ * Router ID.
+ */
+ private Ip4Address routerId;
+ /**
+ * Represents Options like external, opaque capabilities.
+ */
+ private int options;
+ /**
+ * Represents Opaque Enable or not.
+ */
+ private boolean isOpaqueEnable;
+
+ /**
+ * Creates an instance of area implementation.
+ */
+ public OspfAreaImpl() {
+ database = new OspfLsdbImpl(this);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ OspfAreaImpl that = (OspfAreaImpl) o;
+ return Objects.equal(areaId, that.areaId) &&
+ Objects.equal(routerId, that.routerId) &&
+ Objects.equal(addressRanges.size(), that.addressRanges.size()) &&
+ Objects.equal(transitCapability, that.transitCapability) &&
+ Objects.equal(externalRoutingCapability, that.externalRoutingCapability) &&
+ Objects.equal(stubCost, that.stubCost) &&
+ Objects.equal(interfacesLst.size(), that.interfacesLst.size()) &&
+ Objects.equal(database, that.database);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(areaId, routerId, addressRanges, transitCapability, externalRoutingCapability,
+ stubCost, interfacesLst, database);
+ }
+
+ /**
+ * Gets the router id.
+ *
+ * @return router id
+ */
+ public Ip4Address routerId() {
+ return routerId;
+ }
+
+ /**
+ * Sets the router id.
+ *
+ * @param routerId router id
+ */
+ @JsonProperty("routerId")
+ public void setRouterId(Ip4Address routerId) {
+ this.routerId = routerId;
+ }
+
+ /**
+ * Sets opaque enabled to true or false.
+ *
+ * @param isOpaqueEnable true if opaque enabled else false
+ */
+ @JsonProperty("isOpaqueEnable")
+ public void setIsOpaqueEnabled(boolean isOpaqueEnable) {
+ this.isOpaqueEnable = isOpaqueEnable;
+ }
+
+ /**
+ * Gets is opaque enabled or not.
+ *
+ * @return true if opaque enabled else false
+ */
+ public boolean isOpaqueEnabled() {
+ return this.isOpaqueEnable;
+ }
+
+ /**
+ * Initializes link state database.
+ */
+ public void initializeDb() {
+
+ database.initializeDb();
+ }
+
+ /**
+ * Refreshes the OSPF area information .
+ * Gets called as soon as the interface is down or neighbor full Router LSA is updated.
+ *
+ * @param ospfInterface OSPF interface instance
+ */
+ @Override
+ public void refreshArea(OspfInterface ospfInterface) {
+ OspfInterfaceImpl ospfInterfaceImpl = (OspfInterfaceImpl) ospfInterface;
+ log.debug("Inside refreshArea...!!!");
+ //If interface state is DR build network LSA.
+ if (ospfInterfaceImpl.state() == OspfInterfaceState.DR) {
+ if (ospfInterface.listOfNeighbors().size() > 0) {
+ //Get the NetworkLsa
+ NetworkLsa networkLsa = null;
+ try {
+ networkLsa = buildNetworkLsa(ospfInterface.ipAddress(), ospfInterface.ipNetworkMask());
+ } catch (Exception e) {
+ log.debug("Error while building NetworkLsa {}", e.getMessage());
+ }
+ //Add the NetworkLsa to lsdb
+ database.addLsa(networkLsa, true, ospfInterface);
+ addToOtherNeighborLsaTxList(networkLsa);
+ } else {
+ log.debug("No Neighbors hence not creating NetworkLSA...!!!");
+ }
+ }
+ //Get the router LSA
+ RouterLsa routerLsa = null;
+ try {
+ routerLsa = buildRouterLsa(ospfInterface);
+ } catch (Exception e) {
+ log.debug("Error while building RouterLsa {}", e.getMessage());
+ }
+ //Add the RouterLSA to lsdb
+ database.addLsa(routerLsa, true, ospfInterface);
+ addToOtherNeighborLsaTxList(routerLsa);
+ }
+
+ /**
+ * Builds a network LSA.
+ *
+ * @param interfaceIp interface IP address
+ * @param mask interface network mask
+ * @return NetworkLsa instance
+ * @throws Exception might throws exception
+ */
+ public NetworkLsa buildNetworkLsa(Ip4Address interfaceIp, Ip4Address mask) throws Exception {
+ // generate the Router-LSA for this Area.
+ NetworkLsa networkLsa = new NetworkLsa();
+ networkLsa.setAdvertisingRouter(routerId);
+ networkLsa.setLinkStateId(interfaceIp.toString());
+ networkLsa.setLsType(OspfLsaType.NETWORK.value());
+ networkLsa.setAge(1);
+ networkLsa.setOptions(2);
+ networkLsa.setNetworkMask(mask);
+ //Adding our own router.
+ networkLsa.addAttachedRouter(routerId());
+ Iterator iter = interfacesLst.iterator();
+ OspfInterfaceImpl ospfInterface = null;
+ while (iter.hasNext()) {
+ ospfInterface = (OspfInterfaceImpl) iter.next();
+ if (ospfInterface.ipAddress().equals(interfaceIp)) {
+ break;
+ }
+ }
+ if (ospfInterface != null) {
+ List<OspfNbr> neighborsInFullState = getNeighborsInFullState(ospfInterface);
+ if (neighborsInFullState != null) {
+ for (OspfNbr ospfnbr : neighborsInFullState) {
+ networkLsa.addAttachedRouter(ospfnbr.neighborId());
+ log.debug("Adding attached neighbor:: {}", ospfnbr.neighborId());
+ }
+ }
+ }
+ networkLsa.setLsSequenceNo(database.getLsSequenceNumber(OspfLsaType.NETWORK));
+ //Find the byte length and add it in lsa object
+ ChecksumCalculator checksum = new ChecksumCalculator();
+ byte[] lsaBytes = networkLsa.asBytes();
+ networkLsa.setLsPacketLen(lsaBytes.length);
+ //Convert lsa object to byte again to reflect the packet length which we added.
+ lsaBytes = networkLsa.asBytes();
+ //find the checksum
+ byte[] twoByteChecksum = checksum.calculateLsaChecksum(lsaBytes,
+ OspfUtil.LSAPACKET_CHECKSUM_POS1,
+ OspfUtil.LSAPACKET_CHECKSUM_POS2);
+ int checkSumVal = OspfUtil.byteToInteger(twoByteChecksum);
+ networkLsa.setLsCheckSum(checkSumVal);
+ return networkLsa;
+ }
+
+ /**
+ * Builds Router LSA.
+ *
+ * @param ospfInterface Interface instance
+ * @return routerLsa Router LSA instance
+ * @throws Exception might throws exception
+ */
+ public RouterLsa buildRouterLsa(OspfInterface ospfInterface) throws Exception {
+ // generate the Router-LSA for this Area.
+ RouterLsa routerLsa = new RouterLsa();
+ routerLsa.setAdvertisingRouter(routerId);
+ routerLsa.setLinkStateId(routerId.toString());
+ routerLsa.setLsType(OspfLsaType.ROUTER.value());
+ routerLsa.setAge(1);
+ routerLsa.setOptions(options);
+ routerLsa.setAreaBorderRouter(false);
+ routerLsa.setAsBoundaryRouter(false);
+ routerLsa.setVirtualEndPoint(false);
+ buildLinkForRouterLsa(routerLsa, ospfInterface);
+ routerLsa.setLsSequenceNo(database.getLsSequenceNumber(OspfLsaType.ROUTER));
+ //Find the byte length and add it in lsa object
+ ChecksumCalculator checksum = new ChecksumCalculator();
+ byte[] lsaBytes = routerLsa.asBytes();
+ routerLsa.setLsPacketLen(lsaBytes.length);
+ //Convert lsa object to byte again to reflect the packet length whic we added.
+ lsaBytes = routerLsa.asBytes();
+ //find the checksum
+ byte[] twoByteChecksum = checksum.calculateLsaChecksum(lsaBytes,
+ OspfUtil.LSAPACKET_CHECKSUM_POS1,
+ OspfUtil.LSAPACKET_CHECKSUM_POS2);
+ int checkSumVal = OspfUtil.byteToInteger(twoByteChecksum);
+ routerLsa.setLsCheckSum(checkSumVal);
+ return routerLsa;
+ }
+
+ /**
+ * Builds LSA link for router LSA.
+ *
+ * @param routerLsa router LSA instance
+ * @param ospfInterface interface instance
+ */
+ private void buildLinkForRouterLsa(RouterLsa routerLsa, OspfInterface ospfInterface) {
+ OspfInterfaceImpl nextInterface;
+ Iterator interfaces = interfacesLst.iterator();
+ while (interfaces.hasNext()) {
+ nextInterface = (OspfInterfaceImpl) interfaces.next();
+ if (nextInterface.state() == OspfInterfaceState.DOWN) {
+ continue;
+ } else if (nextInterface.state() == OspfInterfaceState.LOOPBACK) {
+ OspfLsaLink link = new OspfLsaLink();
+ link.setLinkData("-1");
+ link.setLinkId(nextInterface.ipAddress().toString());
+ link.setLinkType(3);
+ link.setMetric(0);
+ link.setTos(0);
+ routerLsa.addRouterLink(link);
+ routerLsa.incrementLinkNo();
+ } else if (nextInterface.state() == OspfInterfaceState.POINT2POINT) {
+ // adding all neighbour routers
+ List<OspfNbr> neighborsInFullState = getNeighborsInFullState(nextInterface);
+ if (neighborsInFullState != null) {
+ log.debug("Adding OspfLsaLink ::neighborsInFullState {}, InterfaceIP: {}",
+ neighborsInFullState.size(), nextInterface.ipAddress());
+ for (OspfNbr ospfnbr : neighborsInFullState) {
+ OspfLsaLink link = new OspfLsaLink();
+ link.setLinkData(nextInterface.ipAddress().toString());
+ link.setLinkId(ospfnbr.neighborId().toString());
+ link.setLinkType(1);
+ link.setMetric(0);
+ link.setTos(0);
+ routerLsa.addRouterLink(link);
+ routerLsa.incrementLinkNo();
+ log.debug("Added OspfLsaLink :: {}, neighborIP: {}, routerLinks: {}",
+ ospfnbr.neighborId(), ospfnbr.neighborIpAddr(), routerLsa.noLink());
+ }
+ }
+ // adding the self address
+ OspfLsaLink link = new OspfLsaLink();
+ link.setLinkData(nextInterface.ipNetworkMask().toString());
+ link.setLinkId(nextInterface.ipAddress().toString());
+ link.setLinkType(3);
+ link.setMetric(0);
+ link.setTos(0);
+ routerLsa.addRouterLink(link);
+ routerLsa.incrementLinkNo();
+ } else {
+ buildLinkForRouterLsaBroadcast(routerLsa, nextInterface);
+ }
+ }
+ }
+
+ /**
+ * Builds LSA link for router LSA.
+ *
+ * @param routerLsa router LSA instance
+ * @param ospfInterface interface instance
+ */
+ private void buildLinkForRouterLsaBroadcast(RouterLsa routerLsa, OspfInterface ospfInterface) {
+ OspfInterfaceImpl ospfInterfaceImpl = (OspfInterfaceImpl) ospfInterface;
+ if (ospfInterfaceImpl.state() == OspfInterfaceState.WAITING) {
+ OspfLsaLink link = new OspfLsaLink();
+ link.setLinkData(ospfInterface.ipNetworkMask().toString());
+ //Link id should be set to ip network number
+ link.setLinkId(ospfInterface.ipAddress().toString());
+ link.setLinkType(3);
+ link.setMetric(0);
+ link.setTos(0);
+ routerLsa.addRouterLink(link);
+ routerLsa.incrementLinkNo();
+ } else if (ospfInterfaceImpl.state() == OspfInterfaceState.DR) {
+ OspfLsaLink link = new OspfLsaLink();
+ link.setLinkData(ospfInterface.ipAddress().toString());
+ link.setLinkId(ospfInterface.ipAddress().toString());
+ link.setLinkType(2);
+ link.setMetric(0);
+ link.setTos(0);
+ routerLsa.addRouterLink(link);
+ routerLsa.incrementLinkNo();
+ } else if (ospfInterfaceImpl.state() == OspfInterfaceState.BDR ||
+ ospfInterfaceImpl.state() == OspfInterfaceState.DROTHER) {
+ OspfLsaLink link = new OspfLsaLink();
+ link.setLinkData(ospfInterface.ipAddress().toString());
+ link.setLinkId(ospfInterface.dr().toString());
+ link.setLinkType(2);
+ link.setMetric(0);
+ link.setTos(0);
+ routerLsa.addRouterLink(link);
+ routerLsa.incrementLinkNo();
+ }
+ }
+
+ /**
+ * Gets the area id.
+ *
+ * @return area id
+ */
+ public Ip4Address areaId() {
+ return areaId;
+ }
+
+ /**
+ * Sets the area id.
+ *
+ * @param areaId area id
+ */
+ @JsonProperty("areaId")
+ public void setAreaId(Ip4Address areaId) {
+ this.areaId = areaId;
+ }
+
+ /**
+ * Gets address range.
+ *
+ * @return list of area address ranges
+ */
+ public List<OspfAreaAddressRange> addressRanges() {
+ return addressRanges;
+ }
+
+ /**
+ * Sets the area address ranges.
+ *
+ * @param addressRanges list of area address range
+ */
+ @JsonProperty("addressRange")
+ public void setAddressRanges(List<OspfAreaAddressRange> addressRanges) {
+ this.addressRanges = addressRanges;
+ }
+
+ /**
+ * Gets is transit capable or not.
+ *
+ * @return true if transit capable, else false
+ */
+ public boolean isTransitCapability() {
+ return transitCapability;
+ }
+
+ /**
+ * Sets transit capability.
+ *
+ * @param transitCapability true if transit capable, else false
+ */
+ @JsonProperty("transitCapability")
+ public void setTransitCapability(boolean transitCapability) {
+ this.transitCapability = transitCapability;
+ }
+
+ /**
+ * Gets external routing capability.
+ *
+ * @return true if external routing capable, else false
+ */
+ public boolean isExternalRoutingCapability() {
+ return externalRoutingCapability;
+ }
+
+ /**
+ * Sets external routing capability.
+ *
+ * @param externalRoutingCapability true if external routing capable, else false
+ */
+ @JsonProperty("externalRoutingCapability")
+ public void setExternalRoutingCapability(boolean externalRoutingCapability) {
+ this.externalRoutingCapability = externalRoutingCapability;
+ }
+
+ /**
+ * Gets the stub cost.
+ *
+ * @return stub cost
+ */
+ public int stubCost() {
+ return stubCost;
+ }
+
+ /**
+ * Sets the stub cost.
+ *
+ * @param stubCost stub cost
+ */
+ @JsonProperty("stubCost")
+ public void setStubCost(int stubCost) {
+ this.stubCost = stubCost;
+ }
+
+ /**
+ * Gets the list of interfaces in this area.
+ *
+ * @return list of interfaces
+ */
+ public List<OspfInterface> getInterfacesLst() {
+ return interfacesLst;
+ }
+
+ /**
+ * Sets the list of interfaces attached to the area.
+ *
+ * @param interfacesLst list of OspfInterface instances
+ */
+ @JsonProperty("interface")
+ public void setInterfacesLst(List<OspfInterface> interfacesLst) {
+ this.interfacesLst = interfacesLst;
+ }
+
+ /**
+ * Checks all neighbors belonging to this area whether they are in state EXCHANGE or LOADING.
+ * Return false if there is at least one, else return true. This Method is used by
+ * "processReceivedLsa()" in the neighbor class.
+ *
+ * @return boolean indicating that there is no Neighbor in Database Exchange
+ */
+ public boolean noNeighborInLsaExchangeProcess() {
+ OspfInterfaceImpl nextInterface;
+ OspfNeighborState nextNeighborState;
+ Iterator interfaces = interfacesLst.iterator();
+ while (interfaces.hasNext()) {
+ nextInterface = (OspfInterfaceImpl) interfaces.next();
+ Iterator neighbors = nextInterface.listOfNeighbors().values().iterator();
+ while (neighbors.hasNext()) {
+ nextNeighborState = ((OspfNbrImpl) neighbors.next()).getState();
+ if (nextNeighborState == OspfNeighborState.EXCHANGE ||
+ nextNeighborState == OspfNeighborState.LOADING) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Gets header of all types of LSAs.
+ *
+ * @param excludeMaxAgeLsa need to include(true) or exclude(false) maxage lsa's
+ * @param isOpaquecapable need to include(true) or exclude(false) Type 10 Opaque lsa's
+ * @return list of lsa header in the lsdb
+ */
+ public List getLsaHeaders(boolean excludeMaxAgeLsa, boolean isOpaquecapable) {
+ return database.getAllLsaHeaders(excludeMaxAgeLsa, isOpaquecapable);
+ }
+
+ /**
+ * Gets the LSA from LSDB based on the input.
+ *
+ * @param lsType type of lsa to form the key
+ * @param linkStateID link state id to form the key
+ * @param advertisingRouter advertising router to form the key
+ * @return lsa wrapper instance which contains the Lsa
+ * @throws Exception might throws exception
+ */
+ public LsaWrapper getLsa(int lsType, String linkStateID, String advertisingRouter) throws Exception {
+ String lsaKey = lsType + "-" + linkStateID + "-" + advertisingRouter;
+ if (lsType == OspfParameters.LINK_LOCAL_OPAQUE_LSA || lsType == OspfParameters.AREA_LOCAL_OPAQUE_LSA ||
+ lsType == OspfParameters.AS_OPAQUE_LSA) {
+ byte[] linkStateAsBytes = InetAddress.getByName(linkStateID).getAddress();
+ int opaqueType = linkStateAsBytes[0];
+ int opaqueId = OspfUtil.byteToInteger(Arrays.copyOfRange(linkStateAsBytes, 1,
+ linkStateAsBytes.length));
+ lsaKey = lsType + "-" + opaqueType + opaqueId + "-" + advertisingRouter;
+ }
+ return database.findLsa(lsType, lsaKey);
+ }
+
+
+ /**
+ * Checks whether an instance of the given LSA exists in the database belonging to this area.
+ * If so return true else false.
+ *
+ * @param lookupLsa ospf LSA instance to lookup
+ * @return LSA wrapper instance which contains the Lsa
+ */
+ public LsaWrapper lsaLookup(OspfLsa lookupLsa) {
+ return database.lsaLookup((LsaHeader) lookupLsa);
+ }
+
+ /**
+ * Checks whether an instance of the given LSA exists in the database belonging to this area.
+ * If so return true else false.
+ *
+ * @param lsa1 OSPF LSA instance to compare
+ * @param lsa2 OSPF LSA instance to compare
+ * @return "same" if both instances are same, "latest" if lsa1 is latest, or "old" if lsa1 is old
+ */
+ public String isNewerOrSameLsa(OspfLsa lsa1, OspfLsa lsa2) {
+ return database.isNewerOrSameLsa((LsaHeader) lsa1, (LsaHeader) lsa2);
+ }
+
+ /**
+ * Methods gets called from ChannelHandler to add the received LSA to LSDB.
+ *
+ * @param ospfLsa OSPF LSA instance
+ * @param ospfInterface OSPF interface instance
+ */
+ public void addLsa(OspfLsa ospfLsa, OspfInterface ospfInterface) throws Exception {
+ //second param is false as lsa from network
+ database.addLsa((LsaHeader) ospfLsa, false, ospfInterface);
+ }
+
+ /**
+ * Methods gets called from ChannelHandler to add the received LSA to LSDB.
+ *
+ * @param ospfLsa OSPF LSA instance
+ * @param isSelfOriginated true if the LSA is self originated. Else false
+ * @param ospfInterface OSPF interface instance
+ */
+ public void addLsa(OspfLsa ospfLsa, boolean isSelfOriginated, OspfInterface ospfInterface)
+ throws Exception {
+ database.addLsa((LsaHeader) ospfLsa, isSelfOriginated, ospfInterface);
+ }
+
+ /**
+ * Adds the LSA to maxAge bin.
+ *
+ * @param key key to add it to LSDB
+ * @param wrapper LSA wrapper instance
+ */
+ public void addLsaToMaxAgeBin(String key, LsaWrapper wrapper) {
+ database.addLsaToMaxAgeBin(key, wrapper);
+ }
+
+ /**
+ * Sets router sequence number for router LSA.
+ *
+ * @param newSequenceNumber sequence number
+ */
+ public void setDbRouterSequenceNumber(long newSequenceNumber) {
+ database.setRouterLsaSeqNo(newSequenceNumber);
+ }
+
+ /**
+ * Methods gets called from ChannelHandler to delete the LSA.
+ *
+ * @param ospfLsa the LSA instance to delete
+ */
+ public void deleteLsa(LsaHeader ospfLsa) {
+ database.deleteLsa(ospfLsa);
+ }
+
+ /**
+ * Removes LSA from bin.
+ *
+ * @param lsaWrapper the LSA wrapper instance to delete
+ */
+ public void removeLsaFromBin(LsaWrapper lsaWrapper) {
+ database.removeLsaFromBin(lsaWrapper);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .omitNullValues()
+ .add("areaID", areaId)
+ .add("stubCost", stubCost)
+ .add("addressRanges", addressRanges)
+ .add("interfacesLst", interfacesLst)
+ .add("transitCapability", transitCapability)
+ .add("externalRoutingCapability", externalRoutingCapability)
+ .toString();
+ }
+
+ /**
+ * Checks all Neighbors belonging to this Area whether they are in state lesser than the EXCHANGE.
+ * <p>
+ * Creates list of such neighbors
+ * <p>
+ * Returns list of neighbors who satisfy the conditions
+ *
+ * @param ospfInterface OSPF interface instance
+ * @return List of interfaces having state lesser than exchange
+ */
+ public List<OspfNbr> getNeighborsInFullState(OspfInterface ospfInterface) {
+
+ List<OspfNbr> listEligibleNeighbors = null;
+ OspfNbrImpl ospfNeighbor = null;
+ OspfNeighborState nextNeighborState;
+ Iterator nbrInterface = ospfInterface.listOfNeighbors().values().iterator();
+ while (nbrInterface.hasNext()) {
+ ospfNeighbor = (OspfNbrImpl) nbrInterface.next();
+ nextNeighborState = ospfNeighbor.getState();
+ if (nextNeighborState.getValue() == OspfNeighborState.FULL.getValue()) {
+ if (listEligibleNeighbors == null) {
+ listEligibleNeighbors = new ArrayList<OspfNbr>();
+ listEligibleNeighbors.add(ospfNeighbor);
+ } else {
+ listEligibleNeighbors.add(ospfNeighbor);
+ }
+ }
+ }
+ return listEligibleNeighbors;
+ }
+
+ /**
+ * Gets the LSDB LSA key from LSA header.
+ *
+ * @param lsaHeader LSA header instance
+ * @return key LSA key
+ */
+ public String getLsaKey(LsaHeader lsaHeader) {
+ return database.getLsaKey(lsaHeader);
+ }
+
+ /**
+ * Adds the received LSA in other neighbors tx list.
+ *
+ * @param recLsa LSA Header instance
+ */
+ public void addToOtherNeighborLsaTxList(LsaHeader recLsa) {
+ //Add the received LSA in other neighbors retransmission list.
+ log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList");
+ List<OspfInterface> ospfInterfaces = getInterfacesLst();
+ for (OspfInterface ospfInterfaceFromArea : ospfInterfaces) {
+ Map neighbors = ospfInterfaceFromArea.listOfNeighbors();
+ for (Object neighborIP : neighbors.keySet()) {
+ OspfNbrImpl nbr = (OspfNbrImpl) neighbors.get(neighborIP);
+ if (nbr.getState().getValue() < OspfNeighborState.EXCHANGE.getValue()) {
+ continue;
+ }
+ String key = database.getLsaKey(recLsa);
+ if (nbr.getState() == OspfNeighborState.EXCHANGE || nbr.getState() == OspfNeighborState.LOADING) {
+ if (nbr.getLsReqList().containsKey(key)) {
+ LsaWrapper lsWrapper = lsaLookup(recLsa);
+ if (lsWrapper != null) {
+ LsaHeader ownLSA = (LsaHeader) lsWrapper.ospfLsa();
+ String status = isNewerOrSameLsa(recLsa, ownLSA);
+ if (status.equals("old")) {
+ continue;
+ } else if (status.equals("same")) {
+ log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: " +
+ "Removing lsa from reTxtList {}", key);
+ nbr.getLsReqList().remove(key);
+ continue;
+ } else {
+ log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: " +
+ "Removing lsa from reTxtList {}", key);
+ nbr.getLsReqList().remove(key);
+ }
+ }
+ }
+ }
+ if (recLsa.advertisingRouter().equals((String) neighborIP)) {
+ continue;
+ }
+ if ((recLsa.lsType() == OspfParameters.LINK_LOCAL_OPAQUE_LSA ||
+ recLsa.lsType() == OspfParameters.AREA_LOCAL_OPAQUE_LSA)) {
+ if (nbr.isOpaqueCapable()) {
+ log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: Adding lsa to reTxtList {}",
+ recLsa);
+ nbr.getReTxList().put(key, recLsa);
+ }
+ } else {
+ log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: Adding lsa to reTxtList {}",
+ recLsa);
+ nbr.getReTxList().put(key, recLsa);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the options value.
+ *
+ * @return options value
+ */
+ public int options() {
+ return options;
+ }
+
+ /**
+ * Sets the options value.
+ *
+ * @param options options value
+ */
+ public void setOptions(int options) {
+ this.options = options;
+ }
+
+ /**
+ * Gets the opaque enabled options value.
+ *
+ * @return opaque enabled options value
+ */
+ public int opaqueEnabledOptions() {
+ return Integer.parseInt(OspfParameters.OPAQUE_ENABLED_OPTION_VALUE, 2);
+ }
+
+ /**
+ * Gets the lsdb instance for this area.
+ *
+ * @return lsdb instance
+ */
+ public OspfLsdb database() {
+ return database;
+ }
+}
\ No newline at end of file