blob: fa032cc557ecc7a2b45084013ae884ca4057de6a [file] [log] [blame]
Jian Li955c20c2016-10-31 01:21:50 +09001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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;
Jian Li955c20c2016-10-31 01:21:50 +090019import org.apache.felix.scr.annotations.Component;
Jian Li955c20c2016-10-31 01:21:50 +090020import org.apache.felix.scr.annotations.Reference;
21import org.apache.felix.scr.annotations.ReferenceCardinality;
Jian Li9b1a45b2017-01-19 13:34:31 -080022import org.apache.felix.scr.annotations.Activate;
23import org.apache.felix.scr.annotations.Deactivate;
24
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
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Li9b1a45b2017-01-19 13:34:31 -080061 protected DeviceProviderRegistry providerRegistry;
62
63 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 protected DeviceService deviceService;
65
66 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jian Li955c20c2016-10-31 01:21:50 +090067 protected CoreService coreService;
68
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 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 Li9b1a45b2017-01-19 13:34:31 -080076 private static final String UNKNOWN = "unknown";
77 private static final String IS_NULL_MSG = "LISP device info is null";
78 private static final String IPADDRESS = "ipaddress";
79 private static final String LISP = "lisp";
80
81 protected DeviceProviderService providerService;
82 private InternalLispRouterListener routerListener = new InternalLispRouterListener();
83
Jian Li955c20c2016-10-31 01:21:50 +090084 private ApplicationId appId;
85
86 /**
87 * Creates a LISP device provider.
88 */
89 public LispDeviceProvider() {
90 super(new ProviderId(SCHEME_NAME, DEVICE_PROVIDER_PACKAGE));
91 }
92
93 @Activate
94 public void activate() {
Jian Li9b1a45b2017-01-19 13:34:31 -080095 providerService = providerRegistry.register(this);
Jian Li955c20c2016-10-31 01:21:50 +090096 appId = coreService.registerApplication(APP_NAME);
Jian Li9b1a45b2017-01-19 13:34:31 -080097 controller.addRouterListener(routerListener);
Jian Li955c20c2016-10-31 01:21:50 +090098 log.info("Started");
99 }
100
101 @Deactivate
102 public void deactivate() {
Jian Li9b1a45b2017-01-19 13:34:31 -0800103 controller.getRouters().forEach(router -> controller.disconnectRouter(
104 new LispRouterId(router.routerId()), true));
105 controller.removeRouterListener(routerListener);
106 providerRegistry.unregister(this);
107 providerService = null;
Jian Li955c20c2016-10-31 01:21:50 +0900108 log.info("Stopped");
109 }
110
111 @Override
112 public void triggerProbe(DeviceId deviceId) {
Jian Li9b1a45b2017-01-19 13:34:31 -0800113 log.info("Triggering probe on device {}", deviceId);
Jian Li955c20c2016-10-31 01:21:50 +0900114 }
115
116 @Override
117 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
118
119 }
120
121 @Override
122 public boolean isReachable(DeviceId deviceId) {
Jian Li9b1a45b2017-01-19 13:34:31 -0800123 // TODO: need to provide a way to send probe message to LISP router,
124 // to check the device reachability.
125 return true;
Jian Li955c20c2016-10-31 01:21:50 +0900126 }
127
128 @Override
129 public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) {
Jian Li9b1a45b2017-01-19 13:34:31 -0800130 log.info("This operation is irrelevant for LISP router");
131 }
Jian Li955c20c2016-10-31 01:21:50 +0900132
Jian Li9b1a45b2017-01-19 13:34:31 -0800133 /**
134 * Adds a LISP router into device store.
135 */
136 private void connectDevice(LispRouterId routerId) {
137 DeviceId deviceId = getDeviceId(routerId.id().toString());
138 Preconditions.checkNotNull(deviceId, IS_NULL_MSG);
139
140 // formulate LISP router object
141 ChassisId cid = new ChassisId();
142 String ipAddress = routerId.id().toString();
143 SparseAnnotations annotations = DefaultAnnotations.builder()
144 .set(IPADDRESS, ipAddress)
145 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase())
146 .build();
147 DeviceDescription deviceDescription = new DefaultDeviceDescription(
148 deviceId.uri(),
149 Device.Type.ROUTER,
150 UNKNOWN, UNKNOWN,
151 UNKNOWN, UNKNOWN,
152 cid, false,
153 annotations);
154 if (deviceService.getDevice(deviceId) == null) {
155 providerService.deviceConnected(deviceId, deviceDescription);
156 }
157 checkAndUpdateDevice(deviceId, deviceDescription);
158 }
159
160 /**
161 * Checks whether a specified device is available.
162 *
163 * @param deviceId device identifier
164 * @param deviceDescription device description
165 */
166 private void checkAndUpdateDevice(DeviceId deviceId, DeviceDescription deviceDescription) {
167 if (deviceService.getDevice(deviceId) == null) {
168 log.warn("LISP router {} has not been added to store", deviceId);
169 } else {
170 boolean isReachable = isReachable(deviceId);
171 if (isReachable && !deviceService.isAvailable(deviceId)) {
172 // TODO: handle the mastership logic
173 } else if (!isReachable && deviceService.isAvailable(deviceId)) {
174 providerService.deviceDisconnected(deviceId);
175 }
176 }
177 }
178
179 /**
180 * Listener for LISP router events.
181 */
182 private class InternalLispRouterListener implements LispRouterListener {
183
184 @Override
185 public void routerAdded(LispRouterId routerId) {
186 connectDevice(routerId);
187 log.debug("LISP router {} added to core.", routerId);
188 }
189
190 @Override
191 public void routerRemoved(LispRouterId routerId) {
192 Preconditions.checkNotNull(routerId, IS_NULL_MSG);
193
194 DeviceId deviceId = getDeviceId(routerId.id().toString());
195 if (deviceService.getDevice(deviceId) != null) {
196 providerService.deviceDisconnected(deviceId);
197 log.debug("LISP router {} removed from LISP controller", deviceId);
198 } else {
199 log.warn("LISP router {} does not exist in the store, " +
200 "or it may already have been removed", deviceId);
201 }
202 }
203
204 @Override
205 public void routerChanged(LispRouterId routerId) {
206
207 }
208 }
209
210 /**
211 * Obtains the DeviceId contains IP address of LISP router.
212 *
213 * @param ip IP address
214 * @return DeviceId device identifier
215 */
216 private DeviceId getDeviceId(String ip) {
217 try {
218 return DeviceId.deviceId(new URI(LISP, ip, null));
219 } catch (URISyntaxException e) {
220 throw new IllegalArgumentException("Unable to build deviceID for device "
221 + ip, e);
222 }
Jian Li955c20c2016-10-31 01:21:50 +0900223 }
224}