All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onosproject.provider.isis.topology.impl.IsisTopologyProvider Maven / Gradle / Ivy

The newest version!
/*
 * 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.provider.isis.topology.impl;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.ChassisId;
import org.onlab.util.Bandwidth;
import org.onosproject.isis.controller.IsisController;
import org.onosproject.isis.controller.topology.IsisLink;
import org.onosproject.isis.controller.topology.IsisLinkListener;
import org.onosproject.isis.controller.topology.IsisLinkTed;
import org.onosproject.isis.controller.topology.IsisRouter;
import org.onosproject.isis.controller.topology.IsisRouterId;
import org.onosproject.isis.controller.topology.IsisRouterListener;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.BandwidthCapacity;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provider which advertises device descriptions to the core.
 */
@Component(immediate = true)
public class IsisTopologyProvider extends AbstractProvider implements DeviceProvider, LinkProvider {

    public static final long PSEUDO_PORT = 0xffffffff;
    public static final String ADMINISTRATIVEGROUP = "administrativeGroup";
    public static final String TE_METRIC = "teMetric";
    public static final String MAXRESERVABLEBANDWIDTH = "maxReservableBandwidth";
    public static final String ROUTERID = "routerId";
    public static final String NEIGHBORID = "neighborId";
    private static final Logger log = getLogger(IsisTopologyProvider.class);
    // Default values for tunable parameters
    private static final String UNKNOWN = "unknown";
    final InternalTopologyProvider listener = new InternalTopologyProvider();
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceProviderRegistry deviceProviderRegistry;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected LinkProviderRegistry linkProviderRegistry;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetworkConfigService networkConfigService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected LinkService linkService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected IsisController controller;
    //This Interface that defines how this provider can interact with the core.
    private LinkProviderService linkProviderService;
    // The interface that defines how this Provider can interact with the core
    private DeviceProviderService deviceProviderService;
    private HashMap> portMap = new HashMap<>();

    /**
     * Creates an ISIS device provider.
     */
    public IsisTopologyProvider() {
        super(new ProviderId("l3", "org.onosproject.provider.isis"));
    }

    @Activate
    public void activate() {
        deviceProviderService = deviceProviderRegistry.register(this);
        linkProviderService = linkProviderRegistry.register(this);
        controller.addRouterListener(listener);
        controller.addLinkListener(listener);
        log.debug("IsisDeviceProvider::activate...!!!!");
    }

    @Deactivate
    public void deactivate() {
        log.debug("IsisDeviceProvider::deactivate...!!!!");
        deviceProviderRegistry.unregister(this);
        deviceProviderService = null;
        linkProviderRegistry.unregister(this);
        linkProviderService = null;
        controller.removeRouterListener(listener);
        controller.removeLinkListener(listener);
    }

    @Override
    public void triggerProbe(DeviceId deviceId) {
        log.debug("IsisDeviceProvider::triggerProbe...!!!!");
    }

    @Override
    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
        log.debug("IsisDeviceProvider::roleChanged...!!!!");
    }

    @Override
    public boolean isReachable(DeviceId deviceId) {
        log.debug("IsisDeviceProvider::isReachable...!!!!");
        return true;
    }

    @Override
    public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) {
        log.debug("IsisDeviceProvider::changePortState...!!!!");
    }

    /**
     * Builds link description.
     *
     * @param isisLink ISIS link instance
     * @return link description
     */
    private LinkDescription buildLinkDes(IsisLink isisLink) {
        long srcAddress = 0;
        long dstAddress = 0;
        boolean localPseduo = false;
        boolean remotePseduo = false;
        String localSystemId = isisLink.localSystemId();
        String remoteSystemId = isisLink.remoteSystemId();
        //Changing of port numbers
        if (isisLink.interfaceIp() != null) {
            //srcAddress = isisLink.interfaceIp().toInt();
            srcAddress = (long) Long.parseUnsignedLong(Integer.toBinaryString(isisLink.interfaceIp().toInt()), 2);
        }
        if (isisLink.neighborIp() != null) {
            //dstAddress = isisLink.neighborIp().toInt();
            dstAddress = (long) Long.parseUnsignedLong(Integer.toBinaryString(isisLink.neighborIp().toInt()), 2);
        }
        DeviceId srcId = DeviceId.deviceId(IsisRouterId.uri(localSystemId));
        DeviceId dstId = DeviceId.deviceId(IsisRouterId.uri(remoteSystemId));
        if (checkIsDis(isisLink.localSystemId())) {
            localPseduo = true;
        } else if (checkIsDis(isisLink.remoteSystemId())) {
            remotePseduo = true;
        } else {
            log.debug("IsisDeviceProvider::buildLinkDes : unknown type.!");
        }

        if (localPseduo && srcAddress == 0) {
            srcAddress = PSEUDO_PORT;
        } else if (remotePseduo && dstAddress == 0) {
            dstAddress = PSEUDO_PORT;
        }

        ConnectPoint src = new ConnectPoint(srcId, PortNumber.portNumber(srcAddress));
        ConnectPoint dst = new ConnectPoint(dstId, PortNumber.portNumber(dstAddress));
        DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
        if (isisLink != null) {
            annotationBuilder = buildAnnotations(annotationBuilder, isisLink);
        }

        return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false, annotationBuilder.build());
    }

    /**
     * Return the DIS value from the systemId.
     *
     * @param systemId system Id.
     * @return return true if DIS else false
     */
    public static boolean checkIsDis(String systemId) {
        StringTokenizer stringTokenizer = new StringTokenizer(systemId, "." + "-");
        int count = 0;
        while (stringTokenizer.hasMoreTokens()) {
            String str = stringTokenizer.nextToken();
            if (count == 3) {
                int x = Integer.parseInt(str);
                if (x > 0) {
                    return true;
                }
            }
            count++;
        }
        return false;
    }

    /**
     * Builds port description.
     *
     * @param deviceId   device ID for the port
     * @param portNumber port number of the link
     * @return list of port description
     */
    private List buildPortDescriptions(DeviceId deviceId,
                                                        PortNumber portNumber) {
        List portList;
        if (portMap.containsKey(deviceId)) {
            portList = portMap.get(deviceId);
        } else {
            portList = new ArrayList<>();
        }
        if (portNumber != null) {
            PortDescription portDescriptions = new DefaultPortDescription(portNumber, true);
            portList.add(portDescriptions);
        }
        portMap.put(deviceId, portList);

        return portList;
    }

    /**
     * Builds the annotation details.
     *
     * @param annotationBuilder default annotation builder instance
     * @param isisLink          ISIS link instance
     * @return annotation builder instance
     */
    private DefaultAnnotations.Builder buildAnnotations(DefaultAnnotations.Builder annotationBuilder,
                                                        IsisLink isisLink) {
        int administrativeGroup = 0;
        long teMetric = 0;
        Bandwidth maxReservableBandwidth = Bandwidth.bps(0);
        String routerId = null;
        String neighborId = null;

        //TE Info
        IsisLinkTed isisLinkTed = isisLink.linkTed();
        log.info("Ted Information:  {}", isisLinkTed.toString());
        administrativeGroup = isisLinkTed.administrativeGroup();
        teMetric = isisLinkTed.teDefaultMetric();
        maxReservableBandwidth = isisLinkTed.maximumReservableLinkBandwidth();
        routerId = isisLink.localSystemId();
        neighborId = isisLink.remoteSystemId();
        annotationBuilder.set(ADMINISTRATIVEGROUP, String.valueOf(administrativeGroup));
        annotationBuilder.set(TE_METRIC, String.valueOf(teMetric));
        annotationBuilder.set(MAXRESERVABLEBANDWIDTH, String.valueOf(maxReservableBandwidth));
        annotationBuilder.set(ROUTERID, String.valueOf(routerId));
        annotationBuilder.set(NEIGHBORID, String.valueOf(neighborId));
        return annotationBuilder;
    }

    /**
     * Internal device provider implementation.
     */
    private class InternalTopologyProvider implements IsisRouterListener, IsisLinkListener {

        @Override
        public void routerAdded(IsisRouter isisRouter) {
            String systemId = isisRouter.systemId();
            log.info("Added device {}", systemId);
            DeviceId deviceId = DeviceId.deviceId(IsisRouterId.uri(systemId));
            Device.Type deviceType = Device.Type.ROUTER;
            //If our routerType is Dr or Bdr type is PSEUDO
            if (isisRouter.isDis()) {
                deviceType = Device.Type.ROUTER;
            } else {
                deviceType = Device.Type.VIRTUAL;
            }
            ChassisId cId = new ChassisId();
            DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
            newBuilder.set(AnnotationKeys.TYPE, "L3");
            newBuilder.set("RouterId", systemId);
            DeviceDescription description =
                    new DefaultDeviceDescription(IsisRouterId.uri(systemId), deviceType, UNKNOWN, UNKNOWN, UNKNOWN,
                                                 UNKNOWN, cId, newBuilder.build());
            deviceProviderService.deviceConnected(deviceId, description);
            System.out.println("Device added: " + systemId);
        }

        @Override
        public void routerRemoved(IsisRouter isisRouter) {
            String systemId = isisRouter.systemId();
            log.info("Delete device {}", systemId);
            DeviceId deviceId = DeviceId.deviceId(IsisRouterId.uri(systemId));
            if (deviceProviderService == null) {
                return;
            }
            deviceProviderService.deviceDisconnected(deviceId);
            log.info("delete device {}", systemId);
        }

        @Override
        public void addLink(IsisLink isisLink) {
            log.debug("Addlink {}", isisLink.localSystemId());

            LinkDescription linkDes = buildLinkDes(isisLink);
            //Updating ports of the link
            //If already link exists, return
            if (linkService.getLink(linkDes.src(), linkDes.dst()) != null || linkProviderService == null) {
                return;
            }
            ConnectPoint destconnectPoint = linkDes.dst();
            PortNumber destport = destconnectPoint.port();
            if (destport.toLong() != 0) {
                deviceProviderService.updatePorts(linkDes.src().deviceId(),
                                                  buildPortDescriptions(linkDes.src().deviceId(),
                                                  linkDes.src().port()));
                deviceProviderService.updatePorts(linkDes.dst().deviceId(),
                                                  buildPortDescriptions(linkDes.dst().deviceId(),
                                                  linkDes.dst().port()));
                registerBandwidth(linkDes, isisLink);
                linkProviderService.linkDetected(linkDes);
                System.out.println("link desc " + linkDes.toString());
            }
        }

        @Override
        public void deleteLink(IsisLink isisLink) {
            log.debug("Delete link {}", isisLink.localSystemId());
            if (linkProviderService == null) {
                return;
            }
            LinkDescription linkDes = buildLinkDes(isisLink);
            linkProviderService.linkVanished(linkDes);
        }

        /**
         * Registers the bandwidth for source and destination points.
         *
         * @param linkDes  link description instance
         * @param isisLink ISIS link instance
         */
        private void registerBandwidth(LinkDescription linkDes, IsisLink isisLink) {
            if (isisLink == null) {
                log.error("Could not able to register bandwidth ");
                return;
            }
            IsisLinkTed isisLinkTed = isisLink.linkTed();
            Bandwidth maxReservableBw = isisLinkTed.maximumReservableLinkBandwidth();
            if (maxReservableBw != null) {
                if (maxReservableBw.compareTo(Bandwidth.bps(0)) == 0) {
                    return;
                }
                //Configure bandwidth for src and dst port
                BandwidthCapacity config = networkConfigService.addConfig(linkDes.src(), BandwidthCapacity.class);
                config.capacity(maxReservableBw).apply();

                config = networkConfigService.addConfig(linkDes.dst(), BandwidthCapacity.class);
                config.capacity(maxReservableBw).apply();
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy