| /* |
| * Copyright 2016-present Open Networking Foundation |
| * |
| * 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.isis.controller.impl; |
| |
| import org.onlab.packet.Ip4Address; |
| import org.onlab.packet.MacAddress; |
| import org.onosproject.isis.controller.IsisInterface; |
| import org.onosproject.isis.controller.IsisInterfaceState; |
| import org.onosproject.isis.controller.IsisNeighbor; |
| import org.onosproject.isis.controller.IsisPduType; |
| import org.onosproject.isis.controller.IsisRouterType; |
| import org.onosproject.isis.io.isispacket.pdu.HelloPdu; |
| import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu; |
| import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu; |
| import org.onosproject.isis.io.util.IsisConstants; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.List; |
| import java.util.concurrent.Executors; |
| import java.util.concurrent.ScheduledExecutorService; |
| import java.util.concurrent.TimeUnit; |
| |
| /** |
| * Representation of an ISIS neighbor. |
| * The first thing an ISIS router must do is find its neighbors and form adjacency. |
| * Each neighbor that the router finds will be represented by this class. |
| */ |
| public class DefaultIsisNeighbor implements IsisNeighbor { |
| private static final Logger log = LoggerFactory.getLogger(DefaultIsisNeighbor.class); |
| private String neighborAreaId; |
| private String neighborSystemId; |
| private Ip4Address interfaceIp; |
| private MacAddress neighborMacAddress; |
| private volatile int holdingTime; |
| private int neighborDownInterval; |
| private IsisRouterType routerType; |
| private String l1LanId; |
| private String l2LanId; |
| private byte localCircuitId; |
| private int localExtendedCircuitId; |
| private IsisInterfaceState neighborState = IsisInterfaceState.INITIAL; |
| private InternalInactivityTimeCheck inActivityTimeCheckTask; |
| private ScheduledExecutorService exServiceInActivity; |
| private InternalHoldingTimeCheck holdingTimeCheckTask; |
| private ScheduledExecutorService exServiceHoldingTimeCheck; |
| private boolean inActivityTimerScheduled = false; |
| private IsisInterface isisInterface; |
| |
| /** |
| * Creates an instance of ISIS neighbor. |
| * |
| * @param helloMessage hello message instance |
| * @param isisInterface ISIS interface instance |
| */ |
| public DefaultIsisNeighbor(HelloPdu helloMessage, IsisInterface isisInterface) { |
| this.neighborMacAddress = helloMessage.sourceMac(); |
| List<String> areaAddresses = helloMessage.areaAddress(); |
| this.neighborAreaId = (areaAddresses != null) ? areaAddresses.get(0) : ""; |
| this.neighborSystemId = helloMessage.sourceId(); |
| List<Ip4Address> interfaceIpAddresses = helloMessage.interfaceIpAddresses(); |
| this.interfaceIp = (helloMessage.interfaceIpAddresses() != null) ? |
| interfaceIpAddresses.get(0) : IsisConstants.DEFAULTIP; |
| this.holdingTime = helloMessage.holdingTime(); |
| neighborDownInterval = holdingTime; |
| this.routerType = IsisRouterType.get(helloMessage.circuitType()); |
| if (helloMessage instanceof L1L2HelloPdu) { |
| if (IsisPduType.L1HELLOPDU == helloMessage.isisPduType()) { |
| l1LanId = ((L1L2HelloPdu) helloMessage).lanId(); |
| } else if (IsisPduType.L2HELLOPDU == helloMessage.isisPduType()) { |
| l2LanId = ((L1L2HelloPdu) helloMessage).lanId(); |
| } |
| } else if (helloMessage instanceof P2PHelloPdu) { |
| this.localCircuitId = ((P2PHelloPdu) helloMessage).localCircuitId(); |
| } |
| this.isisInterface = isisInterface; |
| startHoldingTimeCheck(); |
| log.debug("Neighbor added - {}", neighborMacAddress); |
| } |
| |
| /** |
| * Returns local extended circuit ID. |
| * |
| * @return local extended circuit ID |
| */ |
| public int localExtendedCircuitId() { |
| return localExtendedCircuitId; |
| } |
| |
| /** |
| * Sets local extended circuit ID. |
| * |
| * @param localExtendedCircuitId neighbor extended circuit ID |
| */ |
| public void setLocalExtendedCircuitId(int localExtendedCircuitId) { |
| this.localExtendedCircuitId = localExtendedCircuitId; |
| } |
| |
| /** |
| * Returns neighbor area ID. |
| * |
| * @return neighbor area ID |
| */ |
| public String neighborAreaId() { |
| return neighborAreaId; |
| } |
| |
| /** |
| * Sets neighbor area ID. |
| * |
| * @param neighborAreaId neighbor area ID |
| */ |
| public void setNeighborAreaId(String neighborAreaId) { |
| this.neighborAreaId = neighborAreaId; |
| } |
| |
| /** |
| * Returns neighbor system ID. |
| * |
| * @return neighbor system ID |
| */ |
| public String neighborSystemId() { |
| return neighborSystemId; |
| } |
| |
| /** |
| * Sets neighbor system ID. |
| * |
| * @param neighborSystemId neighbor system ID |
| */ |
| public void setNeighborSystemId(String neighborSystemId) { |
| this.neighborSystemId = neighborSystemId; |
| } |
| |
| /** |
| * Returns interface IP. |
| * |
| * @return interface IP |
| */ |
| public Ip4Address interfaceIp() { |
| return interfaceIp; |
| } |
| |
| /** |
| * Sets interface IP. |
| * |
| * @param interfaceIp IP |
| */ |
| public void setInterfaceIp(Ip4Address interfaceIp) { |
| this.interfaceIp = interfaceIp; |
| } |
| |
| /** |
| * Returns neighbor mac address. |
| * |
| * @return neighborMacAddress neighbor mac address |
| */ |
| public MacAddress neighborMacAddress() { |
| return neighborMacAddress; |
| } |
| |
| /** |
| * Sets neighbor mac address. |
| * |
| * @param neighborMacAddress mac address |
| */ |
| public void setNeighborMacAddress(MacAddress neighborMacAddress) { |
| this.neighborMacAddress = neighborMacAddress; |
| } |
| |
| /** |
| * Returns holding time. |
| * |
| * @return holding time |
| */ |
| public int holdingTime() { |
| return holdingTime; |
| } |
| |
| /** |
| * Sets holding time. |
| * |
| * @param holdingTime holding time |
| */ |
| public void setHoldingTime(int holdingTime) { |
| this.holdingTime = holdingTime; |
| } |
| |
| /** |
| * Returns router type. |
| * |
| * @return router type |
| */ |
| public IsisRouterType routerType() { |
| return routerType; |
| } |
| |
| /** |
| * Sets router type. |
| * |
| * @param routerType router type |
| */ |
| public void setRouterType(IsisRouterType routerType) { |
| this.routerType = routerType; |
| } |
| |
| /** |
| * Returns L1 lan ID. |
| * |
| * @return L1 lan ID |
| */ |
| public String l1LanId() { |
| return l1LanId; |
| } |
| |
| /** |
| * Sets L1 lan ID. |
| * |
| * @param l1LanId L1 lan ID |
| */ |
| public void setL1LanId(String l1LanId) { |
| this.l1LanId = l1LanId; |
| } |
| |
| /** |
| * Returns L2 lan ID. |
| * |
| * @return L2 lan ID |
| */ |
| public String l2LanId() { |
| return l2LanId; |
| } |
| |
| /** |
| * Sets L2 lan ID. |
| * |
| * @param l2LanId L2 lan ID |
| */ |
| public void setL2LanId(String l2LanId) { |
| this.l2LanId = l2LanId; |
| } |
| |
| /** |
| * Gets the neighbor interface state. |
| * |
| * @return neighbor interface state |
| */ |
| public IsisInterfaceState interfaceState() { |
| return neighborState; |
| } |
| |
| /** |
| * Sets the neighbor interface state. |
| * |
| * @param neighborState the neighbor interface state |
| */ |
| public void setNeighborState(IsisInterfaceState neighborState) { |
| this.neighborState = neighborState; |
| } |
| |
| /** |
| * Returns local circuit ID. |
| * |
| * @return local circuit ID |
| */ |
| public byte localCircuitId() { |
| return localCircuitId; |
| } |
| |
| /** |
| * Sets local circuit ID. |
| * |
| * @param localCircuitId local circuit ID |
| */ |
| public void setLocalCircuitId(byte localCircuitId) { |
| this.localCircuitId = localCircuitId; |
| } |
| |
| /** |
| * Returns neighbor state. |
| * |
| * @return neighbor state |
| */ |
| public IsisInterfaceState neighborState() { |
| return neighborState; |
| } |
| |
| /** |
| * Starts the holding time check timer. |
| */ |
| public void startHoldingTimeCheck() { |
| log.debug("IsisNeighbor::startHoldingTimeCheck"); |
| holdingTimeCheckTask = new InternalHoldingTimeCheck(); |
| exServiceHoldingTimeCheck = Executors.newSingleThreadScheduledExecutor(); |
| exServiceHoldingTimeCheck.scheduleAtFixedRate(holdingTimeCheckTask, 1, |
| 1, TimeUnit.SECONDS); |
| } |
| |
| /** |
| * Stops the holding time check timer. |
| */ |
| public void stopHoldingTimeCheck() { |
| log.debug("IsisNeighbor::stopHoldingTimeCheck "); |
| exServiceHoldingTimeCheck.shutdown(); |
| } |
| |
| /** |
| * Starts the inactivity timer. |
| */ |
| public void startInactivityTimeCheck() { |
| if (!inActivityTimerScheduled) { |
| log.debug("IsisNeighbor::startInactivityTimeCheck"); |
| inActivityTimeCheckTask = new InternalInactivityTimeCheck(); |
| exServiceInActivity = Executors.newSingleThreadScheduledExecutor(); |
| exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, neighborDownInterval, |
| neighborDownInterval, TimeUnit.SECONDS); |
| inActivityTimerScheduled = true; |
| } |
| } |
| |
| /** |
| * Stops the inactivity timer. |
| */ |
| public void stopInactivityTimeCheck() { |
| if (inActivityTimerScheduled) { |
| log.debug("IsisNeighbor::stopInactivityTimeCheck "); |
| exServiceInActivity.shutdown(); |
| inActivityTimerScheduled = false; |
| } |
| } |
| |
| /** |
| * Called when neighbor is down. |
| */ |
| public void neighborDown() { |
| log.debug("Neighbor Down {} and NeighborSystemId {}", neighborMacAddress, |
| neighborSystemId); |
| stopInactivityTimeCheck(); |
| isisInterface.setL1LanId(IsisConstants.DEFAULTLANID); |
| isisInterface.setL2LanId(IsisConstants.DEFAULTLANID); |
| |
| neighborState = IsisInterfaceState.DOWN; |
| stopInactivityTimeCheck(); |
| stopHoldingTimeCheck(); |
| isisInterface.removeNeighbor(this); |
| |
| isisInterface.isisLsdb().removeTopology(this, isisInterface); |
| } |
| |
| /** |
| * Represents a Task which will do an inactivity time check. |
| */ |
| private class InternalInactivityTimeCheck implements Runnable { |
| /** |
| * Creates an instance. |
| */ |
| InternalInactivityTimeCheck() { |
| } |
| |
| @Override |
| public void run() { |
| log.debug("Neighbor Not Heard till the past router dead interval ."); |
| neighborDown(); |
| } |
| } |
| |
| /** |
| * Represents a Task which will decrement holding time for this neighbor. |
| */ |
| private class InternalHoldingTimeCheck implements Runnable { |
| /** |
| * Creates an instance. |
| */ |
| InternalHoldingTimeCheck() { |
| } |
| |
| @Override |
| public void run() { |
| holdingTime--; |
| if (holdingTime <= 0) { |
| log.debug("Calling neighbor down. Holding time is 0."); |
| neighborDown(); |
| } |
| } |
| } |
| } |