/* * 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 * @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; } }