blob: 8317ae87f2817d36cb4e56b3f81061d88d6fd7b8 [file] [log] [blame]
Jian Li955c20c2016-10-31 01:21:50 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Jian Li955c20c2016-10-31 01:21:50 +09003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.provider.lisp.device.impl;
17
Jian Li9b1a45b2017-01-19 13:34:31 -080018import com.google.common.base.Preconditions;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070019import org.osgi.service.component.annotations.Component;
20import org.osgi.service.component.annotations.Reference;
21import org.osgi.service.component.annotations.ReferenceCardinality;
22import org.osgi.service.component.annotations.Activate;
23import org.osgi.service.component.annotations.Deactivate;
Jian Li9b1a45b2017-01-19 13:34:31 -080024
25import org.onlab.packet.ChassisId;
Jian Li955c20c2016-10-31 01:21:50 +090026import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
Jian Li5e505c62016-12-05 02:44:24 +090028import org.onosproject.lisp.ctl.LispController;
Jian Li9b1a45b2017-01-19 13:34:31 -080029import org.onosproject.lisp.ctl.LispRouterId;
30import org.onosproject.lisp.ctl.LispRouterListener;
31import org.onosproject.net.AnnotationKeys;
32import org.onosproject.net.DefaultAnnotations;
33import org.onosproject.net.Device;
Jian Li955c20c2016-10-31 01:21:50 +090034import org.onosproject.net.DeviceId;
35import org.onosproject.net.MastershipRole;
36import org.onosproject.net.PortNumber;
Jian Li9b1a45b2017-01-19 13:34:31 -080037import org.onosproject.net.SparseAnnotations;
Jian Li955c20c2016-10-31 01:21:50 +090038import org.onosproject.net.device.DeviceProvider;
Jian Li9b1a45b2017-01-19 13:34:31 -080039import org.onosproject.net.device.DeviceProviderRegistry;
40import org.onosproject.net.device.DeviceProviderService;
41import org.onosproject.net.device.DeviceService;
42import org.onosproject.net.device.DeviceDescription;
43import org.onosproject.net.device.DefaultDeviceDescription;
Jian Li955c20c2016-10-31 01:21:50 +090044import org.onosproject.net.provider.AbstractProvider;
45import org.onosproject.net.provider.ProviderId;
46import org.slf4j.Logger;
47import org.slf4j.LoggerFactory;
48
Jian Li9b1a45b2017-01-19 13:34:31 -080049import java.net.URI;
50import java.net.URISyntaxException;
51
Jian Li955c20c2016-10-31 01:21:50 +090052/**
53 * Provider which uses an LISP controller to detect device.
54 */
55@Component(immediate = true)
Jian Li9b1a45b2017-01-19 13:34:31 -080056public class LispDeviceProvider extends AbstractProvider implements DeviceProvider {
Jian Li955c20c2016-10-31 01:21:50 +090057
58 private static final Logger log = LoggerFactory.getLogger(LispDeviceProvider.class);
59
Ray Milkeyd84f89b2018-08-17 14:54:17 -070060 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9b1a45b2017-01-19 13:34:31 -080061 protected DeviceProviderRegistry providerRegistry;
62
Ray Milkeyd84f89b2018-08-17 14:54:17 -070063 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9b1a45b2017-01-19 13:34:31 -080064 protected DeviceService deviceService;
65
Ray Milkeyd84f89b2018-08-17 14:54:17 -070066 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li955c20c2016-10-31 01:21:50 +090067 protected CoreService coreService;
68
Ray Milkeyd84f89b2018-08-17 14:54:17 -070069 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li955c20c2016-10-31 01:21:50 +090070 protected LispController controller;
71
72 private static final String APP_NAME = "org.onosproject.lisp";
73 private static final String SCHEME_NAME = "lisp";
74 private static final String DEVICE_PROVIDER_PACKAGE = "org.onosproject.lisp.provider.device";
75
Jian Lie5aa5df2017-04-02 22:40:56 +090076 private static final String MANUFACTURER = "IETF";
77 private static final String HARDWARE_VERSION = "LISP Reference Router";
78 private static final String SOFTWARE_VERSION = "1.0";
79 private static final String SERIAL_NUMBER = "unknown";
Jian Li9b1a45b2017-01-19 13:34:31 -080080 private static final String IS_NULL_MSG = "LISP device info is null";
81 private static final String IPADDRESS = "ipaddress";
82 private static final String LISP = "lisp";
83
84 protected DeviceProviderService providerService;
85 private InternalLispRouterListener routerListener = new InternalLispRouterListener();
86
Jian Li955c20c2016-10-31 01:21:50 +090087 private ApplicationId appId;
88
89 /**
90 * Creates a LISP device provider.
91 */
92 public LispDeviceProvider() {
93 super(new ProviderId(SCHEME_NAME, DEVICE_PROVIDER_PACKAGE));
94 }
95
96 @Activate
97 public void activate() {
Jian Li9b1a45b2017-01-19 13:34:31 -080098 providerService = providerRegistry.register(this);
Jian Li955c20c2016-10-31 01:21:50 +090099 appId = coreService.registerApplication(APP_NAME);
Jian Li9b1a45b2017-01-19 13:34:31 -0800100 controller.addRouterListener(routerListener);
Jian Li955c20c2016-10-31 01:21:50 +0900101 log.info("Started");
102 }
103
104 @Deactivate
105 public void deactivate() {
Jian Li9b1a45b2017-01-19 13:34:31 -0800106 controller.getRouters().forEach(router -> controller.disconnectRouter(
107 new LispRouterId(router.routerId()), true));
108 controller.removeRouterListener(routerListener);
109 providerRegistry.unregister(this);
110 providerService = null;
Jian Li955c20c2016-10-31 01:21:50 +0900111 log.info("Stopped");
112 }
113
114 @Override
115 public void triggerProbe(DeviceId deviceId) {
Jian Li9b1a45b2017-01-19 13:34:31 -0800116 log.info("Triggering probe on device {}", deviceId);
Jian Li955c20c2016-10-31 01:21:50 +0900117 }
118
119 @Override
120 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
121
122 }
123
124 @Override
125 public boolean isReachable(DeviceId deviceId) {
Jian Li9b1a45b2017-01-19 13:34:31 -0800126 // TODO: need to provide a way to send probe message to LISP router,
127 // to check the device reachability.
128 return true;
Jian Li955c20c2016-10-31 01:21:50 +0900129 }
130
131 @Override
132 public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) {
Jian Li9b1a45b2017-01-19 13:34:31 -0800133 log.info("This operation is irrelevant for LISP router");
134 }
Jian Li955c20c2016-10-31 01:21:50 +0900135
Jian Li9b1a45b2017-01-19 13:34:31 -0800136 /**
137 * Adds a LISP router into device store.
138 */
139 private void connectDevice(LispRouterId routerId) {
140 DeviceId deviceId = getDeviceId(routerId.id().toString());
141 Preconditions.checkNotNull(deviceId, IS_NULL_MSG);
142
143 // formulate LISP router object
144 ChassisId cid = new ChassisId();
145 String ipAddress = routerId.id().toString();
146 SparseAnnotations annotations = DefaultAnnotations.builder()
147 .set(IPADDRESS, ipAddress)
148 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase())
149 .build();
150 DeviceDescription deviceDescription = new DefaultDeviceDescription(
151 deviceId.uri(),
152 Device.Type.ROUTER,
Jian Lie5aa5df2017-04-02 22:40:56 +0900153 MANUFACTURER, HARDWARE_VERSION,
154 SOFTWARE_VERSION, SERIAL_NUMBER,
Jian Li9b1a45b2017-01-19 13:34:31 -0800155 cid, false,
156 annotations);
157 if (deviceService.getDevice(deviceId) == null) {
158 providerService.deviceConnected(deviceId, deviceDescription);
159 }
160 checkAndUpdateDevice(deviceId, deviceDescription);
161 }
162
163 /**
164 * Checks whether a specified device is available.
165 *
166 * @param deviceId device identifier
167 * @param deviceDescription device description
168 */
169 private void checkAndUpdateDevice(DeviceId deviceId, DeviceDescription deviceDescription) {
170 if (deviceService.getDevice(deviceId) == null) {
171 log.warn("LISP router {} has not been added to store", deviceId);
172 } else {
173 boolean isReachable = isReachable(deviceId);
174 if (isReachable && !deviceService.isAvailable(deviceId)) {
175 // TODO: handle the mastership logic
176 } else if (!isReachable && deviceService.isAvailable(deviceId)) {
177 providerService.deviceDisconnected(deviceId);
178 }
179 }
180 }
181
182 /**
183 * Listener for LISP router events.
184 */
185 private class InternalLispRouterListener implements LispRouterListener {
186
187 @Override
188 public void routerAdded(LispRouterId routerId) {
189 connectDevice(routerId);
190 log.debug("LISP router {} added to core.", routerId);
191 }
192
193 @Override
194 public void routerRemoved(LispRouterId routerId) {
195 Preconditions.checkNotNull(routerId, IS_NULL_MSG);
196
197 DeviceId deviceId = getDeviceId(routerId.id().toString());
198 if (deviceService.getDevice(deviceId) != null) {
199 providerService.deviceDisconnected(deviceId);
200 log.debug("LISP router {} removed from LISP controller", deviceId);
201 } else {
202 log.warn("LISP router {} does not exist in the store, " +
203 "or it may already have been removed", deviceId);
204 }
205 }
206
207 @Override
208 public void routerChanged(LispRouterId routerId) {
209
210 }
211 }
212
213 /**
214 * Obtains the DeviceId contains IP address of LISP router.
215 *
216 * @param ip IP address
217 * @return DeviceId device identifier
218 */
219 private DeviceId getDeviceId(String ip) {
220 try {
221 return DeviceId.deviceId(new URI(LISP, ip, null));
222 } catch (URISyntaxException e) {
223 throw new IllegalArgumentException("Unable to build deviceID for device "
224 + ip, e);
225 }
Jian Li955c20c2016-10-31 01:21:50 +0900226 }
227}