blob: 8730814c4eef4dd480ca981ca9f42e4d71d9187b [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.util.Bandwidth;
import org.onosproject.isis.controller.IsisNetworkType;
import org.onosproject.isis.controller.LspWrapper;
import org.onosproject.isis.controller.impl.topology.DefaultIsisLink;
import org.onosproject.isis.controller.impl.topology.DefaultIsisLinkInformation;
import org.onosproject.isis.controller.impl.topology.DefaultIsisLinkTed;
import org.onosproject.isis.controller.impl.topology.DefaultIsisRouter;
import org.onosproject.isis.controller.impl.topology.TopologyForDeviceAndLinkImpl;
import org.onosproject.isis.controller.topology.IsisLink;
import org.onosproject.isis.controller.topology.IsisLinkTed;
import org.onosproject.isis.controller.topology.IsisRouter;
import org.onosproject.isis.controller.topology.LinkInformation;
import org.onosproject.isis.io.isispacket.pdu.LsPdu;
import org.onosproject.isis.io.isispacket.tlv.IsExtendedReachability;
import org.onosproject.isis.io.isispacket.tlv.IsisTlv;
import org.onosproject.isis.io.isispacket.tlv.NeighborForExtendedIs;
import org.onosproject.isis.io.isispacket.tlv.subtlv.AdministrativeGroup;
import org.onosproject.isis.io.isispacket.tlv.subtlv.InterfaceIpAddress;
import org.onosproject.isis.io.isispacket.tlv.subtlv.MaximumBandwidth;
import org.onosproject.isis.io.isispacket.tlv.subtlv.MaximumReservableBandwidth;
import org.onosproject.isis.io.isispacket.tlv.subtlv.NeighborIpAddress;
import org.onosproject.isis.io.isispacket.tlv.subtlv.TrafficEngineeringMetric;
import org.onosproject.isis.io.isispacket.tlv.subtlv.TrafficEngineeringSubTlv;
import org.onosproject.isis.io.isispacket.tlv.subtlv.UnreservedBandwidth;
import org.onosproject.isis.io.util.IsisConstants;
import org.onosproject.isis.io.util.IsisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
/**
* Representation of LSP event consumer.
*/
public class LspEventConsumer implements Runnable {
private static final Logger log = LoggerFactory.getLogger(LspEventConsumer.class);
private BlockingQueue queue = null;
private Controller controller = null;
private TopologyForDeviceAndLinkImpl deviceAndLink = new TopologyForDeviceAndLinkImpl();
private Map<String, IsisRouter> isisRouterDetails = new LinkedHashMap<>();
/**
* Creates an instance of this.
*
* @param queue blocking queue instance
* @param controller controller instance
*/
public LspEventConsumer(BlockingQueue queue, Controller controller) {
this.queue = queue;
this.controller = controller;
}
@Override
public void run() {
try {
while (true) {
if (!queue.isEmpty()) {
LspWrapper wrapper = (LspWrapper) queue.take();
LsPdu lsPdu = (LsPdu) wrapper.lsPdu();
if (wrapper.lspProcessing().equals(IsisConstants.LSPREMOVED)) {
callTopologyToRemoveInfo(lsPdu);
} else if (wrapper.lspProcessing().equals(IsisConstants.LSPADDED)) {
callTopologyToSendInfo(lsPdu, wrapper.isisInterface().networkType(),
wrapper.isisInterface().systemId() + ".00");
}
}
}
} catch (Exception e) {
log.debug("Error::LspsForProvider::{}", e.getMessage());
}
}
/**
* Sends topology information to core.
*
* @param lsPdu ls pdu instance
* @param isisNetworkType ISIS network type
* @param ownSystemId own system ID
*/
private void callTopologyToSendInfo(LsPdu lsPdu, IsisNetworkType isisNetworkType,
String ownSystemId) {
if ((lsPdu.lspId().equals(ownSystemId + "-00"))) {
return;
}
sendDeviceInfo(createDeviceInfo(lsPdu));
for (IsisTlv isisTlv : lsPdu.tlvs()) {
if (isisTlv instanceof IsExtendedReachability) {
IsExtendedReachability isExtendedReachability = (IsExtendedReachability) isisTlv;
List<NeighborForExtendedIs> neighbours = isExtendedReachability.neighbours();
for (NeighborForExtendedIs teTlv : neighbours) {
String neighbor = teTlv.neighborId();
IsisRouter isisRouter = isisRouterDetails.get(neighbor);
if (isisRouter != null) {
IsisRouter sourceRouter = isisRouterDetails.get(IsisUtil.removeTailingZeros(lsPdu.lspId()));
IsisRouter destinationRouter = isisRouter;
if (sourceRouter.isDis()) {
LinkInformation linkInformation = createLinkInfo(sourceRouter.systemId(),
destinationRouter.systemId(),
sourceRouter.interfaceId(),
destinationRouter.interfaceId(), lsPdu);
controller.addLinkDetails(createIsisLink(linkInformation, lsPdu));
} else if (destinationRouter.isDis()) {
LinkInformation linkInformation1 = createLinkInfo(destinationRouter.systemId(),
sourceRouter.systemId(),
destinationRouter.interfaceId(),
sourceRouter.interfaceId(), lsPdu);
controller.addLinkDetails(createIsisLink(linkInformation1, lsPdu));
} else {
LinkInformation linkInformation = createLinkInfo(sourceRouter.systemId(),
destinationRouter.systemId(),
sourceRouter.interfaceId(),
destinationRouter.interfaceId(), lsPdu);
controller.addLinkDetails(createIsisLink(linkInformation, lsPdu));
LinkInformation linkInformation1 = createLinkInfo(destinationRouter.systemId(),
sourceRouter.systemId(),
destinationRouter.interfaceId(),
sourceRouter.interfaceId(), lsPdu);
controller.addLinkDetails(createIsisLink(linkInformation1, lsPdu));
}
}
}
}
}
}
/**
* Removes topology information from core.
*
* @param lsPdu ls pdu instance
*/
private void callTopologyToRemoveInfo(LsPdu lsPdu) {
String routerId = IsisUtil.removeTailingZeros(lsPdu.lspId());
IsisRouter isisRouter = isisRouterDetails.get(routerId);
removeDeviceInfo(isisRouter);
removeLinkInfo(lsPdu);
}
/**
* Sends the device information to topology provider.
*
* @param isisRouter ISIS router instance
*/
private void sendDeviceInfo(IsisRouter isisRouter) {
if (isisRouter.systemId() != null) {
controller.addDeviceDetails(isisRouter);
}
}
/**
* Creates Device instance.
*
* @param lsPdu ISIS LSPDU instance
* @return isisRouter isisRouter instance
*/
public IsisRouter createDeviceInfo(LsPdu lsPdu) {
IsisRouter isisRouter = createIsisRouter(lsPdu);
if (isisRouter.systemId() != null) {
isisRouterDetails.put(isisRouter.systemId(), isisRouter);
}
return isisRouter;
}
/**
* Creates ISIS router instance.
*
* @param lsPdu lsp instance
* @return isisRouter instance
*/
private IsisRouter createIsisRouter(LsPdu lsPdu) {
IsisRouter isisRouter = new DefaultIsisRouter();
if (IsisUtil.checkIsDis(lsPdu.lspId())) {
isisRouter.setDis(true);
} else {
isisRouter.setDis(false);
}
isisRouter.setSystemId(IsisUtil.removeTailingZeros(lsPdu.lspId()));
for (IsisTlv isisTlv : lsPdu.tlvs()) {
if (isisTlv instanceof IsExtendedReachability) {
IsExtendedReachability isExtendedReachability = (IsExtendedReachability) isisTlv;
List<NeighborForExtendedIs> neighbours = isExtendedReachability.neighbours();
for (NeighborForExtendedIs teTlv : neighbours) {
List<TrafficEngineeringSubTlv> teSubTlvs = teTlv.teSubTlv();
for (TrafficEngineeringSubTlv teSubTlv : teSubTlvs) {
if (teSubTlv instanceof InterfaceIpAddress) {
InterfaceIpAddress localIpAddress = (InterfaceIpAddress) teSubTlv;
isisRouter.setInterfaceId(localIpAddress.localInterfaceIPAddress());
} else if (teSubTlv instanceof NeighborIpAddress) {
NeighborIpAddress neighborIpAddress = (NeighborIpAddress) teSubTlv;
isisRouter.setNeighborRouterId(neighborIpAddress.neighborIPAddress());
}
}
}
}
}
if (isisRouter.interfaceId() == null) {
isisRouter.setInterfaceId(IsisConstants.DEFAULTIP);
}
if (isisRouter.neighborRouterId() == null) {
isisRouter.setNeighborRouterId(IsisConstants.DEFAULTIP);
}
return isisRouter;
}
/**
* Creates link information.
*
* @param localSystemId local system ID
* @param remoteSystemId remote system ID
* @return link information
* @param interfaceIp interface address
* @param neighborIp neighbor address
* @param lsPdu link state PDU instance
* @return link information instance
*/
public LinkInformation createLinkInfo(String localSystemId, String remoteSystemId,
Ip4Address interfaceIp, Ip4Address neighborIp,
LsPdu lsPdu) {
String linkId = "link:" + localSystemId + "-" + remoteSystemId;
LinkInformation linkInformation = new DefaultIsisLinkInformation();
linkInformation.setInterfaceIp(interfaceIp);
linkInformation.setNeighborIp(neighborIp);
linkInformation.setLinkId(linkId);
linkInformation.setAlreadyCreated(false);
linkInformation.setLinkDestinationId(remoteSystemId);
linkInformation.setLinkSourceId(localSystemId);
return linkInformation;
}
/**
* Removes the device information from topology provider.
*
* @param isisRouter ISIS router instance
*/
private void removeDeviceInfo(IsisRouter isisRouter) {
if (isisRouter.systemId() != null) {
controller.removeDeviceDetails(isisRouter);
}
isisRouterDetails.remove(isisRouter.systemId());
}
/**
* Removes the link information from topology provider.
*
* @param lsPdu ls pdu instance
*/
private void removeLinkInfo(LsPdu lsPdu) {
Map<String, LinkInformation> linkInformationList = deviceAndLink.removeLinkInfo(lsPdu.lspId());
for (String key : linkInformationList.keySet()) {
LinkInformation linkInformation = linkInformationList.get(key);
controller.removeLinkDetails(createIsisLink(linkInformation, lsPdu));
}
}
/**
* Creates ISIS link instance.
*
* @param linkInformation link information instance
* @return isisLink instance
*/
private IsisLink createIsisLink(LinkInformation linkInformation, LsPdu lsPdu) {
IsisLink isisLink = new DefaultIsisLink();
isisLink.setLocalSystemId(linkInformation.linkSourceId());
isisLink.setRemoteSystemId(linkInformation.linkDestinationId());
isisLink.setInterfaceIp(linkInformation.interfaceIp());
isisLink.setNeighborIp(linkInformation.neighborIp());
isisLink.setLinkTed(createIsisLinkTedInfo(lsPdu));
return isisLink;
}
/**
* Creates the ISIS link TED information.
*
* @param lsPdu link state PDU
* @return isisLinkTed
*/
public IsisLinkTed createIsisLinkTedInfo(LsPdu lsPdu) {
IsisLinkTed isisLinkTed = new DefaultIsisLinkTed();
for (IsisTlv isisTlv : lsPdu.tlvs()) {
if (isisTlv instanceof IsExtendedReachability) {
IsExtendedReachability isExtendedReachability = (IsExtendedReachability) isisTlv;
List<NeighborForExtendedIs> neighbours = isExtendedReachability.neighbours();
for (NeighborForExtendedIs teTlv : neighbours) {
List<TrafficEngineeringSubTlv> teSubTlvs = teTlv.teSubTlv();
for (TrafficEngineeringSubTlv teSubTlv : teSubTlvs) {
if (teSubTlv instanceof AdministrativeGroup) {
AdministrativeGroup ag = (AdministrativeGroup) teSubTlv;
isisLinkTed.setAdministrativeGroup(ag.administrativeGroup());
}
if (teSubTlv instanceof InterfaceIpAddress) {
InterfaceIpAddress localIpAddress = (InterfaceIpAddress) teSubTlv;
isisLinkTed.setIpv4InterfaceAddress(localIpAddress.localInterfaceIPAddress());
}
if (teSubTlv instanceof NeighborIpAddress) {
NeighborIpAddress neighborIpAddress = (NeighborIpAddress) teSubTlv;
isisLinkTed.setIpv4NeighborAddress(neighborIpAddress.neighborIPAddress());
}
if (teSubTlv instanceof TrafficEngineeringMetric) {
TrafficEngineeringMetric teM = (TrafficEngineeringMetric) teSubTlv;
isisLinkTed.setTeDefaultMetric(teM.getTrafficEngineeringMetricValue());
}
if (teSubTlv instanceof MaximumBandwidth) {
MaximumBandwidth maxLinkBandwidth = (MaximumBandwidth) teSubTlv;
isisLinkTed.setMaximumLinkBandwidth(
Bandwidth.bps(maxLinkBandwidth.getMaximumBandwidthValue()));
}
if (teSubTlv instanceof MaximumReservableBandwidth) {
MaximumReservableBandwidth maxReservableBw = (MaximumReservableBandwidth) teSubTlv;
isisLinkTed.setMaximumReservableLinkBandwidth(
Bandwidth.bps(maxReservableBw.getMaximumBandwidthValue()));
}
if (teSubTlv instanceof UnreservedBandwidth) {
UnreservedBandwidth unReservedBandwidth = (UnreservedBandwidth) teSubTlv;
List<Bandwidth> bandwidthList = new ArrayList<>();
List<Float> unReservedBandwidthList = unReservedBandwidth.unReservedBandwidthValue();
for (Float unReservedBandwidthFloatValue : unReservedBandwidthList) {
Bandwidth bandwidth = Bandwidth.bps(unReservedBandwidthFloatValue);
bandwidthList.add(bandwidth);
}
isisLinkTed.setUnreservedBandwidth(bandwidthList);
}
}
}
}
}
return isisLinkTed;
}
}