blob: 0839eb54225cd4b923d85568736f47263494ab49 [file] [log] [blame]
/*
* 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.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();
}
}
}
}