blob: 702d61a423489510a3d10e7b186fab74a37f6055 [file] [log] [blame]
/*
* 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.provider.ospf.topology.impl;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ip4Address;
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.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.onosproject.ospf.controller.OspfController;
import org.onosproject.ospf.controller.OspfLinkTed;
import org.onosproject.ospf.controller.OspfRouter;
import org.onosproject.ospf.controller.OspfRouterId;
import org.onosproject.ospf.controller.OspfRouterListener;
import org.onosproject.ospf.controller.OspfLinkListener;
import org.slf4j.Logger;
import java.util.LinkedList;
import java.util.List;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Provider which advertises device descriptions to the core.
*/
@Component(immediate = true)
public class OspfTopologyProvider extends AbstractProvider implements DeviceProvider, LinkProvider {
public static final long PSEUDO_PORT = 0xffffffff;
private static final Logger log = getLogger(OspfTopologyProvider.class);
// Default values for tunable parameters
private static final String UNKNOWN = "unknown";
final InternalTopologyProvider listener = new InternalTopologyProvider();
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected DeviceProviderRegistry deviceProviderRegistry;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected LinkProviderRegistry linkProviderRegistry;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected LinkService linkService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected OspfController 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;
/**
* Creates an OSPF device provider.
*/
public OspfTopologyProvider() {
super(new ProviderId("l3", "org.onosproject.provider.ospf"));
}
@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);
log.info("deactivated...!!!");
}
@Override
public boolean isReachable(DeviceId deviceId) {
return true;
}
@Override
public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) {
log.info("changePortState on device {}", deviceId);
}
@Override
public void triggerProbe(DeviceId deviceId) {
log.info("Triggering probe on device {}", deviceId);
}
@Override
public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
log.info("Accepting mastership role change for device {}", deviceId);
}
/**
* Builds link description.
*
* @param ospfRouter OSPF router instance
* @param ospfLinkTed OSPF link TED instance
* @return link description instance
*/
private LinkDescription buildLinkDes(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
long srcAddress = 0;
long dstAddress = 0;
boolean localPseduo = false;
//Changing of port numbers
srcAddress = Ip4Address.valueOf(ospfRouter.routerIp().toString()).toInt();
dstAddress = Ip4Address.valueOf(ospfRouter.neighborRouterId().toString()).toInt();
DeviceId srcId = DeviceId.deviceId(OspfRouterId.uri(ospfRouter.routerIp()));
DeviceId dstId = DeviceId.deviceId(OspfRouterId.uri(ospfRouter.neighborRouterId()));
if (ospfRouter.isDr()) {
localPseduo = true;
}
if (localPseduo && srcAddress == 0) {
srcAddress = PSEUDO_PORT;
}
ConnectPoint src = new ConnectPoint(srcId, PortNumber.portNumber(srcAddress));
ConnectPoint dst = new ConnectPoint(dstId, PortNumber.portNumber(dstAddress));
return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false);
}
/**
* Internal topology Provider implementation.
*/
protected class InternalTopologyProvider implements OspfRouterListener, OspfLinkListener {
@Override
public void routerAdded(OspfRouter ospfRouter) {
String routerId = ospfRouter.routerIp().toString();
log.info("Added device {}", routerId);
DeviceId deviceId = DeviceId.deviceId(OspfRouterId.uri(ospfRouter.routerIp()));
Device.Type deviceType = Device.Type.ROUTER;
//If our routerType is Dr or Bdr type is PSEUDO
if (ospfRouter.isDr()) {
deviceType = Device.Type.ROUTER;
} else {
deviceType = Device.Type.VIRTUAL;
}
//deviceId = DeviceId.deviceId(routerDetails);
ChassisId cId = new ChassisId();
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set(AnnotationKeys.TYPE, "l3");
newBuilder.set("routerId", routerId);
DeviceDescription description =
new DefaultDeviceDescription(OspfRouterId.uri(ospfRouter.routerIp()),
deviceType, UNKNOWN, UNKNOWN, UNKNOWN,
UNKNOWN, cId, newBuilder.build());
deviceProviderService.deviceConnected(deviceId, description);
}
@Override
public void routerRemoved(OspfRouter ospfRouter) {
String routerId = ospfRouter.routerIp().toString();
log.info("Delete device {}", routerId);
DeviceId deviceId = DeviceId.deviceId(OspfRouterId.uri(ospfRouter.routerIp()));
if (deviceProviderService == null) {
return;
}
deviceProviderService.deviceDisconnected(deviceId);
log.info("delete device {}", routerId);
}
@Override
public void addLink(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
log.debug("Addlink {}", ospfRouter.routerIp());
LinkDescription linkDes = buildLinkDes(ospfRouter, ospfLinkTed);
//If already link exists, return
if (linkService.getLink(linkDes.src(), linkDes.dst()) != null || linkProviderService == null) {
return;
}
//Updating ports of the link
List<PortDescription> srcPortDescriptions = new LinkedList<>();
srcPortDescriptions.add(DefaultPortDescription.builder()
.withPortNumber(linkDes.src().port()).isEnabled(true).build());
deviceProviderService.updatePorts(linkDes.src().deviceId(), srcPortDescriptions);
List<PortDescription> dstPortDescriptions = new LinkedList<>();
dstPortDescriptions.add(DefaultPortDescription.builder()
.withPortNumber(linkDes.dst().port()).isEnabled(true).build());
deviceProviderService.updatePorts(linkDes.dst().deviceId(), dstPortDescriptions);
linkProviderService.linkDetected(linkDes);
}
@Override
public void deleteLink(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
log.debug("Delete link {}", ospfRouter.routerIp().toString());
if (linkProviderService == null) {
return;
}
LinkDescription linkDes = buildLinkDes(ospfRouter, ospfLinkTed);
//Updating ports of the link
List<PortDescription> srcPortDescriptions = new LinkedList<>();
srcPortDescriptions.add(DefaultPortDescription.builder()
.withPortNumber(linkDes.src().port()).isEnabled(true).build());
deviceProviderService.updatePorts(linkDes.src().deviceId(), srcPortDescriptions);
List<PortDescription> dstPortDescriptions = new LinkedList<>();
dstPortDescriptions.add(DefaultPortDescription.builder()
.withPortNumber(linkDes.dst().port()).isEnabled(true).build());
deviceProviderService.updatePorts(linkDes.dst().deviceId(), dstPortDescriptions);
linkProviderService.linkVanished(linkDes);
}
@Override
public void routerChanged(OspfRouter ospfRouter) {
log.info("Router changed is not supported currently");
}
}
}