blob: a8d3fc7d61c9cc1c682a525476deec3abce512c0 [file] [log] [blame]
sunish vk7bdf4d42016-06-24 12:29:43 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
sunish vk7bdf4d42016-06-24 12:29:43 +05303 *
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 */
16
17package org.onosproject.provider.isis.topology.impl;
18
Ray Milkeyd84f89b2018-08-17 14:54:17 -070019import org.osgi.service.component.annotations.Activate;
20import org.osgi.service.component.annotations.Component;
21import org.osgi.service.component.annotations.Deactivate;
22import org.osgi.service.component.annotations.Reference;
23import org.osgi.service.component.annotations.ReferenceCardinality;
sunish vk7bdf4d42016-06-24 12:29:43 +053024import org.onlab.packet.ChassisId;
25import org.onlab.util.Bandwidth;
26import org.onosproject.isis.controller.IsisController;
27import org.onosproject.isis.controller.topology.IsisLink;
28import org.onosproject.isis.controller.topology.IsisLinkListener;
29import org.onosproject.isis.controller.topology.IsisLinkTed;
30import org.onosproject.isis.controller.topology.IsisRouter;
31import org.onosproject.isis.controller.topology.IsisRouterId;
32import org.onosproject.isis.controller.topology.IsisRouterListener;
33import org.onosproject.net.AnnotationKeys;
34import org.onosproject.net.ConnectPoint;
35import org.onosproject.net.DefaultAnnotations;
36import org.onosproject.net.Device;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.Link;
39import org.onosproject.net.MastershipRole;
40import org.onosproject.net.PortNumber;
41import org.onosproject.net.config.NetworkConfigService;
42import org.onosproject.net.config.basics.BandwidthCapacity;
43import org.onosproject.net.device.DefaultDeviceDescription;
44import org.onosproject.net.device.DefaultPortDescription;
45import org.onosproject.net.device.DeviceDescription;
46import org.onosproject.net.device.DeviceProvider;
47import org.onosproject.net.device.DeviceProviderRegistry;
48import org.onosproject.net.device.DeviceProviderService;
49import org.onosproject.net.device.PortDescription;
50import org.onosproject.net.link.DefaultLinkDescription;
51import org.onosproject.net.link.LinkDescription;
52import org.onosproject.net.link.LinkProvider;
53import org.onosproject.net.link.LinkProviderRegistry;
54import org.onosproject.net.link.LinkProviderService;
55import org.onosproject.net.link.LinkService;
56import org.onosproject.net.provider.AbstractProvider;
57import org.onosproject.net.provider.ProviderId;
58import org.slf4j.Logger;
59
60import java.util.ArrayList;
61import java.util.HashMap;
62import java.util.List;
63import java.util.StringTokenizer;
64
Palash Kalaa8e1bfa2017-03-30 16:42:23 +090065import static com.google.common.base.Preconditions.checkNotNull;
sunish vk7bdf4d42016-06-24 12:29:43 +053066import static org.slf4j.LoggerFactory.getLogger;
67
68/**
69 * Provider which advertises device descriptions to the core.
70 */
71@Component(immediate = true)
72public class IsisTopologyProvider extends AbstractProvider implements DeviceProvider, LinkProvider {
73
74 public static final long PSEUDO_PORT = 0xffffffff;
75 public static final String ADMINISTRATIVEGROUP = "administrativeGroup";
76 public static final String TE_METRIC = "teMetric";
77 public static final String MAXRESERVABLEBANDWIDTH = "maxReservableBandwidth";
78 public static final String ROUTERID = "routerId";
79 public static final String NEIGHBORID = "neighborId";
80 private static final Logger log = getLogger(IsisTopologyProvider.class);
81 // Default values for tunable parameters
82 private static final String UNKNOWN = "unknown";
83 final InternalTopologyProvider listener = new InternalTopologyProvider();
Ray Milkeyd84f89b2018-08-17 14:54:17 -070084 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sunish vk7bdf4d42016-06-24 12:29:43 +053085 protected DeviceProviderRegistry deviceProviderRegistry;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070086 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sunish vk7bdf4d42016-06-24 12:29:43 +053087 protected LinkProviderRegistry linkProviderRegistry;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070088 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sunish vk7bdf4d42016-06-24 12:29:43 +053089 protected NetworkConfigService networkConfigService;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070090 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sunish vk7bdf4d42016-06-24 12:29:43 +053091 protected LinkService linkService;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070092 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sunish vk7bdf4d42016-06-24 12:29:43 +053093 protected IsisController controller;
94 //This Interface that defines how this provider can interact with the core.
95 private LinkProviderService linkProviderService;
96 // The interface that defines how this Provider can interact with the core
97 private DeviceProviderService deviceProviderService;
98 private HashMap<DeviceId, List<PortDescription>> portMap = new HashMap<>();
99
100 /**
101 * Creates an ISIS device provider.
102 */
103 public IsisTopologyProvider() {
104 super(new ProviderId("l3", "org.onosproject.provider.isis"));
105 }
106
107 @Activate
108 public void activate() {
109 deviceProviderService = deviceProviderRegistry.register(this);
110 linkProviderService = linkProviderRegistry.register(this);
111 controller.addRouterListener(listener);
112 controller.addLinkListener(listener);
113 log.debug("IsisDeviceProvider::activate...!!!!");
114 }
115
116 @Deactivate
117 public void deactivate() {
118 log.debug("IsisDeviceProvider::deactivate...!!!!");
119 deviceProviderRegistry.unregister(this);
120 deviceProviderService = null;
121 linkProviderRegistry.unregister(this);
122 linkProviderService = null;
123 controller.removeRouterListener(listener);
124 controller.removeLinkListener(listener);
125 }
126
127 @Override
128 public void triggerProbe(DeviceId deviceId) {
129 log.debug("IsisDeviceProvider::triggerProbe...!!!!");
130 }
131
132 @Override
133 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
134 log.debug("IsisDeviceProvider::roleChanged...!!!!");
135 }
136
137 @Override
138 public boolean isReachable(DeviceId deviceId) {
139 log.debug("IsisDeviceProvider::isReachable...!!!!");
140 return true;
141 }
142
143 @Override
144 public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) {
145 log.debug("IsisDeviceProvider::changePortState...!!!!");
146 }
147
148 /**
149 * Builds link description.
150 *
151 * @param isisLink ISIS link instance
152 * @return link description
153 */
154 private LinkDescription buildLinkDes(IsisLink isisLink) {
Palash Kalaa8e1bfa2017-03-30 16:42:23 +0900155 checkNotNull(isisLink);
sunish vk7bdf4d42016-06-24 12:29:43 +0530156 long srcAddress = 0;
157 long dstAddress = 0;
158 boolean localPseduo = false;
159 boolean remotePseduo = false;
160 String localSystemId = isisLink.localSystemId();
161 String remoteSystemId = isisLink.remoteSystemId();
162 //Changing of port numbers
163 if (isisLink.interfaceIp() != null) {
164 //srcAddress = isisLink.interfaceIp().toInt();
165 srcAddress = (long) Long.parseUnsignedLong(Integer.toBinaryString(isisLink.interfaceIp().toInt()), 2);
166 }
167 if (isisLink.neighborIp() != null) {
168 //dstAddress = isisLink.neighborIp().toInt();
169 dstAddress = (long) Long.parseUnsignedLong(Integer.toBinaryString(isisLink.neighborIp().toInt()), 2);
170 }
171 DeviceId srcId = DeviceId.deviceId(IsisRouterId.uri(localSystemId));
172 DeviceId dstId = DeviceId.deviceId(IsisRouterId.uri(remoteSystemId));
173 if (checkIsDis(isisLink.localSystemId())) {
174 localPseduo = true;
175 } else if (checkIsDis(isisLink.remoteSystemId())) {
176 remotePseduo = true;
177 } else {
178 log.debug("IsisDeviceProvider::buildLinkDes : unknown type.!");
179 }
180
181 if (localPseduo && srcAddress == 0) {
182 srcAddress = PSEUDO_PORT;
183 } else if (remotePseduo && dstAddress == 0) {
184 dstAddress = PSEUDO_PORT;
185 }
186
187 ConnectPoint src = new ConnectPoint(srcId, PortNumber.portNumber(srcAddress));
188 ConnectPoint dst = new ConnectPoint(dstId, PortNumber.portNumber(dstAddress));
189 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
Palash Kalaa8e1bfa2017-03-30 16:42:23 +0900190
191 annotationBuilder = buildAnnotations(annotationBuilder, isisLink);
sunish vk7bdf4d42016-06-24 12:29:43 +0530192
193 return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false, annotationBuilder.build());
194 }
195
196 /**
197 * Return the DIS value from the systemId.
198 *
199 * @param systemId system Id.
200 * @return return true if DIS else false
201 */
202 public static boolean checkIsDis(String systemId) {
203 StringTokenizer stringTokenizer = new StringTokenizer(systemId, "." + "-");
204 int count = 0;
205 while (stringTokenizer.hasMoreTokens()) {
206 String str = stringTokenizer.nextToken();
207 if (count == 3) {
208 int x = Integer.parseInt(str);
209 if (x > 0) {
210 return true;
211 }
212 }
213 count++;
214 }
215 return false;
216 }
217
218 /**
219 * Builds port description.
220 *
221 * @param deviceId device ID for the port
222 * @param portNumber port number of the link
223 * @return list of port description
224 */
225 private List<PortDescription> buildPortDescriptions(DeviceId deviceId,
226 PortNumber portNumber) {
227 List<PortDescription> portList;
228 if (portMap.containsKey(deviceId)) {
229 portList = portMap.get(deviceId);
230 } else {
231 portList = new ArrayList<>();
232 }
233 if (portNumber != null) {
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800234 PortDescription portDescriptions = DefaultPortDescription.builder()
235 .withPortNumber(portNumber).isEnabled(true).build();
sunish vk7bdf4d42016-06-24 12:29:43 +0530236 portList.add(portDescriptions);
237 }
238 portMap.put(deviceId, portList);
239
240 return portList;
241 }
242
243 /**
244 * Builds the annotation details.
245 *
246 * @param annotationBuilder default annotation builder instance
247 * @param isisLink ISIS link instance
248 * @return annotation builder instance
249 */
250 private DefaultAnnotations.Builder buildAnnotations(DefaultAnnotations.Builder annotationBuilder,
251 IsisLink isisLink) {
252 int administrativeGroup = 0;
253 long teMetric = 0;
254 Bandwidth maxReservableBandwidth = Bandwidth.bps(0);
255 String routerId = null;
256 String neighborId = null;
257
258 //TE Info
259 IsisLinkTed isisLinkTed = isisLink.linkTed();
260 log.info("Ted Information: {}", isisLinkTed.toString());
261 administrativeGroup = isisLinkTed.administrativeGroup();
262 teMetric = isisLinkTed.teDefaultMetric();
263 maxReservableBandwidth = isisLinkTed.maximumReservableLinkBandwidth();
264 routerId = isisLink.localSystemId();
265 neighborId = isisLink.remoteSystemId();
266 annotationBuilder.set(ADMINISTRATIVEGROUP, String.valueOf(administrativeGroup));
267 annotationBuilder.set(TE_METRIC, String.valueOf(teMetric));
268 annotationBuilder.set(MAXRESERVABLEBANDWIDTH, String.valueOf(maxReservableBandwidth));
269 annotationBuilder.set(ROUTERID, String.valueOf(routerId));
270 annotationBuilder.set(NEIGHBORID, String.valueOf(neighborId));
271 return annotationBuilder;
272 }
273
274 /**
275 * Internal device provider implementation.
276 */
277 private class InternalTopologyProvider implements IsisRouterListener, IsisLinkListener {
278
279 @Override
280 public void routerAdded(IsisRouter isisRouter) {
281 String systemId = isisRouter.systemId();
282 log.info("Added device {}", systemId);
283 DeviceId deviceId = DeviceId.deviceId(IsisRouterId.uri(systemId));
284 Device.Type deviceType = Device.Type.ROUTER;
285 //If our routerType is Dr or Bdr type is PSEUDO
286 if (isisRouter.isDis()) {
287 deviceType = Device.Type.ROUTER;
288 } else {
289 deviceType = Device.Type.VIRTUAL;
290 }
291 ChassisId cId = new ChassisId();
292 DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
293 newBuilder.set(AnnotationKeys.TYPE, "L3");
294 newBuilder.set("RouterId", systemId);
295 DeviceDescription description =
296 new DefaultDeviceDescription(IsisRouterId.uri(systemId), deviceType, UNKNOWN, UNKNOWN, UNKNOWN,
297 UNKNOWN, cId, newBuilder.build());
298 deviceProviderService.deviceConnected(deviceId, description);
299 System.out.println("Device added: " + systemId);
300 }
301
302 @Override
303 public void routerRemoved(IsisRouter isisRouter) {
304 String systemId = isisRouter.systemId();
305 log.info("Delete device {}", systemId);
306 DeviceId deviceId = DeviceId.deviceId(IsisRouterId.uri(systemId));
307 if (deviceProviderService == null) {
308 return;
309 }
310 deviceProviderService.deviceDisconnected(deviceId);
311 log.info("delete device {}", systemId);
312 }
313
314 @Override
315 public void addLink(IsisLink isisLink) {
316 log.debug("Addlink {}", isisLink.localSystemId());
317
318 LinkDescription linkDes = buildLinkDes(isisLink);
319 //Updating ports of the link
320 //If already link exists, return
321 if (linkService.getLink(linkDes.src(), linkDes.dst()) != null || linkProviderService == null) {
322 return;
323 }
324 ConnectPoint destconnectPoint = linkDes.dst();
325 PortNumber destport = destconnectPoint.port();
326 if (destport.toLong() != 0) {
327 deviceProviderService.updatePorts(linkDes.src().deviceId(),
328 buildPortDescriptions(linkDes.src().deviceId(),
329 linkDes.src().port()));
330 deviceProviderService.updatePorts(linkDes.dst().deviceId(),
331 buildPortDescriptions(linkDes.dst().deviceId(),
332 linkDes.dst().port()));
333 registerBandwidth(linkDes, isisLink);
334 linkProviderService.linkDetected(linkDes);
335 System.out.println("link desc " + linkDes.toString());
336 }
337 }
338
339 @Override
340 public void deleteLink(IsisLink isisLink) {
341 log.debug("Delete link {}", isisLink.localSystemId());
342 if (linkProviderService == null) {
343 return;
344 }
345 LinkDescription linkDes = buildLinkDes(isisLink);
346 linkProviderService.linkVanished(linkDes);
347 }
348
349 /**
350 * Registers the bandwidth for source and destination points.
351 *
352 * @param linkDes link description instance
353 * @param isisLink ISIS link instance
354 */
355 private void registerBandwidth(LinkDescription linkDes, IsisLink isisLink) {
356 if (isisLink == null) {
357 log.error("Could not able to register bandwidth ");
358 return;
359 }
360 IsisLinkTed isisLinkTed = isisLink.linkTed();
361 Bandwidth maxReservableBw = isisLinkTed.maximumReservableLinkBandwidth();
362 if (maxReservableBw != null) {
363 if (maxReservableBw.compareTo(Bandwidth.bps(0)) == 0) {
364 return;
365 }
366 //Configure bandwidth for src and dst port
367 BandwidthCapacity config = networkConfigService.addConfig(linkDes.src(), BandwidthCapacity.class);
368 config.capacity(maxReservableBw).apply();
369
370 config = networkConfigService.addConfig(linkDes.dst(), BandwidthCapacity.class);
371 config.capacity(maxReservableBw).apply();
372 }
373 }
374 }
375}