| /* |
| * Copyright 2016-present 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; |
| } |
| } |