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