[ONOS-5749] Initial implementation LISP device provider
Change-Id: Ie1ac2ff82c62717fc8e2b045f964d026fe30effa
diff --git a/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/LispController.java b/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/LispController.java
index 1a3641d..bbfd5c2 100644
--- a/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/LispController.java
+++ b/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/LispController.java
@@ -36,6 +36,24 @@
Iterable<LispRouter> getSubscribedRouters();
/**
+ * Connects to a specific LISP router.
+ * If the connection is established, it creates and adds the device to
+ * ONOS core as a LISP router.
+ *
+ * @param routerId router identifier
+ * @return LispRouter LISP router
+ */
+ LispRouter connectRouter(LispRouterId routerId);
+
+ /**
+ * Disconnects a LISP router and notify router removal event.
+ *
+ * @param routerId router identifier
+ * @param remove true only if want to notify router removal event
+ */
+ void disconnectRouter(LispRouterId routerId, boolean remove);
+
+ /**
* Obtains the actual router for the given LispRouterId.
*
* @param routerId the router to fetch
diff --git a/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispControllerAdapter.java b/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispControllerAdapter.java
index aeebeeb..f628c5d 100644
--- a/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispControllerAdapter.java
+++ b/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispControllerAdapter.java
@@ -30,6 +30,16 @@
}
@Override
+ public LispRouter connectRouter(LispRouterId routerId) {
+ return null;
+ }
+
+ @Override
+ public void disconnectRouter(LispRouterId routerId, boolean remove) {
+
+ }
+
+ @Override
public LispRouter getRouter(LispRouterId routerId) {
return null;
}
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispControllerImpl.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispControllerImpl.java
index 7fa1e98..a409d94 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispControllerImpl.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispControllerImpl.java
@@ -186,6 +186,30 @@
}
@Override
+ public LispRouter connectRouter(LispRouterId routerId) {
+ if (connectedRouters.containsKey(routerId)) {
+ log.debug("LISP router {} is already existing", routerId);
+ return connectedRouters.get(routerId);
+ } else {
+ // TODO: currently we do not consider to add LISP router from netcfg
+ log.warn("Adding router from netcfg is not supported currently");
+ return null;
+ }
+ }
+
+ @Override
+ public void disconnectRouter(LispRouterId routerId, boolean remove) {
+ if (!connectedRouters.containsKey(routerId)) {
+ log.warn("LISP router {} is not existing", routerId);
+ } else {
+ connectedRouters.get(routerId).disconnectRouter();
+ if (remove) {
+ agent.removeConnectedRouter(routerId);
+ }
+ }
+ }
+
+ @Override
public LispRouter getRouter(LispRouterId routerId) {
return connectedRouters.get(routerId);
}
diff --git a/providers/lisp/device/src/main/java/org/onosproject/provider/lisp/device/impl/LispDeviceProvider.java b/providers/lisp/device/src/main/java/org/onosproject/provider/lisp/device/impl/LispDeviceProvider.java
index 0183959..fa032cc 100644
--- a/providers/lisp/device/src/main/java/org/onosproject/provider/lisp/device/impl/LispDeviceProvider.java
+++ b/providers/lisp/device/src/main/java/org/onosproject/provider/lisp/device/impl/LispDeviceProvider.java
@@ -15,33 +15,55 @@
*/
package org.onosproject.provider.lisp.device.impl;
-import org.apache.felix.scr.annotations.Activate;
+import com.google.common.base.Preconditions;
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.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+
+import org.onlab.packet.ChassisId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.lisp.ctl.LispController;
+import org.onosproject.lisp.ctl.LispRouterId;
+import org.onosproject.lisp.ctl.LispRouterListener;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.device.DeviceProvider;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceProviderService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.net.URI;
+import java.net.URISyntaxException;
+
/**
* Provider which uses an LISP controller to detect device.
*/
@Component(immediate = true)
-public class LispDeviceProvider extends AbstractProvider
- implements DeviceProvider {
+public class LispDeviceProvider extends AbstractProvider implements DeviceProvider {
private static final Logger log = LoggerFactory.getLogger(LispDeviceProvider.class);
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceProviderRegistry providerRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -51,6 +73,14 @@
private static final String SCHEME_NAME = "lisp";
private static final String DEVICE_PROVIDER_PACKAGE = "org.onosproject.lisp.provider.device";
+ private static final String UNKNOWN = "unknown";
+ private static final String IS_NULL_MSG = "LISP device info is null";
+ private static final String IPADDRESS = "ipaddress";
+ private static final String LISP = "lisp";
+
+ protected DeviceProviderService providerService;
+ private InternalLispRouterListener routerListener = new InternalLispRouterListener();
+
private ApplicationId appId;
/**
@@ -62,18 +92,25 @@
@Activate
public void activate() {
+ providerService = providerRegistry.register(this);
appId = coreService.registerApplication(APP_NAME);
+ controller.addRouterListener(routerListener);
log.info("Started");
}
@Deactivate
public void deactivate() {
+ controller.getRouters().forEach(router -> controller.disconnectRouter(
+ new LispRouterId(router.routerId()), true));
+ controller.removeRouterListener(routerListener);
+ providerRegistry.unregister(this);
+ providerService = null;
log.info("Stopped");
}
@Override
public void triggerProbe(DeviceId deviceId) {
-
+ log.info("Triggering probe on device {}", deviceId);
}
@Override
@@ -83,11 +120,105 @@
@Override
public boolean isReachable(DeviceId deviceId) {
- return false;
+ // TODO: need to provide a way to send probe message to LISP router,
+ // to check the device reachability.
+ return true;
}
@Override
public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) {
+ log.info("This operation is irrelevant for LISP router");
+ }
+ /**
+ * Adds a LISP router into device store.
+ */
+ private void connectDevice(LispRouterId routerId) {
+ DeviceId deviceId = getDeviceId(routerId.id().toString());
+ Preconditions.checkNotNull(deviceId, IS_NULL_MSG);
+
+ // formulate LISP router object
+ ChassisId cid = new ChassisId();
+ String ipAddress = routerId.id().toString();
+ SparseAnnotations annotations = DefaultAnnotations.builder()
+ .set(IPADDRESS, ipAddress)
+ .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase())
+ .build();
+ DeviceDescription deviceDescription = new DefaultDeviceDescription(
+ deviceId.uri(),
+ Device.Type.ROUTER,
+ UNKNOWN, UNKNOWN,
+ UNKNOWN, UNKNOWN,
+ cid, false,
+ annotations);
+ if (deviceService.getDevice(deviceId) == null) {
+ providerService.deviceConnected(deviceId, deviceDescription);
+ }
+ checkAndUpdateDevice(deviceId, deviceDescription);
+ }
+
+ /**
+ * Checks whether a specified device is available.
+ *
+ * @param deviceId device identifier
+ * @param deviceDescription device description
+ */
+ private void checkAndUpdateDevice(DeviceId deviceId, DeviceDescription deviceDescription) {
+ if (deviceService.getDevice(deviceId) == null) {
+ log.warn("LISP router {} has not been added to store", deviceId);
+ } else {
+ boolean isReachable = isReachable(deviceId);
+ if (isReachable && !deviceService.isAvailable(deviceId)) {
+ // TODO: handle the mastership logic
+ } else if (!isReachable && deviceService.isAvailable(deviceId)) {
+ providerService.deviceDisconnected(deviceId);
+ }
+ }
+ }
+
+ /**
+ * Listener for LISP router events.
+ */
+ private class InternalLispRouterListener implements LispRouterListener {
+
+ @Override
+ public void routerAdded(LispRouterId routerId) {
+ connectDevice(routerId);
+ log.debug("LISP router {} added to core.", routerId);
+ }
+
+ @Override
+ public void routerRemoved(LispRouterId routerId) {
+ Preconditions.checkNotNull(routerId, IS_NULL_MSG);
+
+ DeviceId deviceId = getDeviceId(routerId.id().toString());
+ if (deviceService.getDevice(deviceId) != null) {
+ providerService.deviceDisconnected(deviceId);
+ log.debug("LISP router {} removed from LISP controller", deviceId);
+ } else {
+ log.warn("LISP router {} does not exist in the store, " +
+ "or it may already have been removed", deviceId);
+ }
+ }
+
+ @Override
+ public void routerChanged(LispRouterId routerId) {
+
+ }
+ }
+
+ /**
+ * Obtains the DeviceId contains IP address of LISP router.
+ *
+ * @param ip IP address
+ * @return DeviceId device identifier
+ */
+ private DeviceId getDeviceId(String ip) {
+ try {
+ return DeviceId.deviceId(new URI(LISP, ip, null));
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException("Unable to build deviceID for device "
+ + ip, e);
+ }
}
}