blob: 7807d5f9c7c619aa1a0da9f402d1aae99522c1f6 [file] [log] [blame]
Shashikanth VH1ca26ce2015-11-20 23:19:49 +05301/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5 * the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11 * specific language governing permissions and limitations under the License.
12 */
13
14package org.onosproject.provider.bgp.topology.impl;
15
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053016import static org.onosproject.bgp.controller.BgpDpid.uri;
17import static org.onosproject.net.DeviceId.deviceId;
Priyanka Bfc51c952016-03-26 14:30:33 +053018import static org.onosproject.net.Device.Type.ROUTER;
19import static org.onosproject.net.Device.Type.VIRTUAL;
20
21import java.util.List;
22import java.util.Set;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053023
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053024import org.onlab.packet.ChassisId;
25import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Reference;
29import org.apache.felix.scr.annotations.ReferenceCardinality;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053030import org.onosproject.bgp.controller.BgpController;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053031import org.onosproject.bgp.controller.BgpDpid;
Priyanka Bfc51c952016-03-26 14:30:33 +053032import org.onosproject.bgp.controller.BgpLinkListener;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053033import org.onosproject.bgp.controller.BgpNodeListener;
Priyanka Bfc51c952016-03-26 14:30:33 +053034import org.onosproject.bgpio.exceptions.BgpParseException;
35import org.onosproject.bgpio.protocol.linkstate.BgpLinkLSIdentifier;
36import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
37import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053038import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
Priyanka Bfc51c952016-03-26 14:30:33 +053039import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors;
40import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
41import org.onosproject.bgpio.types.AutonomousSystemTlv;
42import org.onosproject.bgpio.types.BgpLSIdentifierTlv;
43import org.onosproject.bgpio.types.BgpValueType;
44import org.onosproject.bgpio.types.IPv4AddressTlv;
45import org.onosproject.bgpio.types.IsIsNonPseudonode;
46import org.onosproject.bgpio.types.IsIsPseudonode;
47import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
48import org.onosproject.bgpio.types.OspfNonPseudonode;
49import org.onosproject.bgpio.types.OspfPseudonode;
50import org.onosproject.core.CoreService;
51import org.onosproject.net.AnnotationKeys;
52import org.onosproject.net.ConnectPoint;
53import org.onosproject.net.DefaultAnnotations;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053054import org.onosproject.net.Device;
55import org.onosproject.net.DeviceId;
Priyanka Bfc51c952016-03-26 14:30:33 +053056import org.onosproject.net.Link;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053057import org.onosproject.net.MastershipRole;
Saurav Dasa2d37502016-03-25 17:50:40 -070058import org.onosproject.net.PortNumber;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053059import org.onosproject.net.device.DefaultDeviceDescription;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053060import org.onosproject.net.device.DeviceDescription;
61import org.onosproject.net.device.DeviceProvider;
62import org.onosproject.net.device.DeviceProviderRegistry;
63import org.onosproject.net.device.DeviceProviderService;
Priyanka Bfc51c952016-03-26 14:30:33 +053064import org.onosproject.net.device.DeviceService;
65import org.onosproject.net.link.DefaultLinkDescription;
66import org.onosproject.net.link.LinkDescription;
67import org.onosproject.net.link.LinkProvider;
68import org.onosproject.net.link.LinkProviderRegistry;
69import org.onosproject.net.link.LinkProviderService;
70import org.onosproject.net.link.LinkService;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053071import org.onosproject.net.provider.AbstractProvider;
72import org.onosproject.net.provider.ProviderId;
73import org.slf4j.Logger;
74import org.slf4j.LoggerFactory;
75
76/**
77 * Provider which uses an BGP controller to detect network infrastructure topology.
78 */
79@Component(immediate = true)
Priyanka Bfc51c952016-03-26 14:30:33 +053080public class BgpTopologyProvider extends AbstractProvider implements DeviceProvider, LinkProvider {
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053081
82 public BgpTopologyProvider() {
83 super(new ProviderId("bgp", "org.onosproject.provider.bgp"));
84 }
85
86 private static final Logger log = LoggerFactory.getLogger(BgpTopologyProvider.class);
87
88 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053089 protected DeviceProviderRegistry deviceProviderRegistry;
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Priyanka Bfc51c952016-03-26 14:30:33 +053092 protected LinkProviderRegistry linkProviderRegistry;
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053095 protected BgpController controller;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +053096
Priyanka Bfc51c952016-03-26 14:30:33 +053097 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected LinkService linkService;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected DeviceService deviceService;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected CoreService coreService;
105
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530106 private DeviceProviderService deviceProviderService;
Priyanka Bfc51c952016-03-26 14:30:33 +0530107 private LinkProviderService linkProviderService;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530108
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530109 private InternalBgpProvider listener = new InternalBgpProvider();
110 private static final String UNKNOWN = "unknown";
Priyanka Bfc51c952016-03-26 14:30:33 +0530111 public static final long IDENTIFIER_SET = 0x100000000L;
112 public static final String AS_NUMBER = "asNumber";
113 public static final String DOMAIN_IDENTIFIER = "domainIdentifier";
114 public static final String ROUTING_UNIVERSE = "routingUniverse";
115 public static final long PSEUDO_PORT = 0xffffffff;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530116
117 @Activate
118 public void activate() {
Priyanka Bfc51c952016-03-26 14:30:33 +0530119 log.debug("BgpTopologyProvider activate");
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530120 deviceProviderService = deviceProviderRegistry.register(this);
Priyanka Bfc51c952016-03-26 14:30:33 +0530121 linkProviderService = linkProviderRegistry.register(this);
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530122 controller.addListener(listener);
Priyanka Bfc51c952016-03-26 14:30:33 +0530123 controller.addLinkListener(listener);
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530124 }
125
126 @Deactivate
127 public void deactivate() {
Priyanka Bfc51c952016-03-26 14:30:33 +0530128 log.debug("BgpTopologyProvider deactivate");
129 deviceProviderRegistry.unregister(this);
130 deviceProviderService = null;
131 linkProviderRegistry.unregister(this);
132 linkProviderService = null;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530133 controller.removeListener(listener);
Priyanka Bfc51c952016-03-26 14:30:33 +0530134 controller.removeLinkListener(listener);
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530135 }
136
137 /*
138 * Implements device and link update.
139 */
Priyanka Bfc51c952016-03-26 14:30:33 +0530140 private class InternalBgpProvider implements BgpNodeListener, BgpLinkListener {
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530141
142 @Override
Priyanka Bfc51c952016-03-26 14:30:33 +0530143 public void addNode(BgpNodeLSNlriVer4 nodeNlri, PathAttrNlriDetails details) {
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530144 log.debug("Add node {}", nodeNlri.toString());
145
146 if (deviceProviderService == null) {
147 return;
148 }
Priyanka Bfc51c952016-03-26 14:30:33 +0530149 Device.Type deviceType = ROUTER;
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530150 BgpDpid nodeUri = new BgpDpid(nodeNlri);
151 DeviceId deviceId = deviceId(uri(nodeUri.toString()));
152 ChassisId cId = new ChassisId();
153
Priyanka Bfc51c952016-03-26 14:30:33 +0530154 DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
155
156 newBuilder.set(AnnotationKeys.TYPE, "L3");
157 newBuilder.set(ROUTING_UNIVERSE, Long.toString(nodeNlri.getIdentifier()));
158
159 List<BgpValueType> tlvs = nodeNlri.getLocalNodeDescriptors().getNodedescriptors().getSubTlvs();
160 for (BgpValueType tlv : tlvs) {
161 if (tlv instanceof AutonomousSystemTlv) {
162 newBuilder.set(AS_NUMBER, Integer.toString(((AutonomousSystemTlv) tlv).getAsNum()));
163 } else if (tlv instanceof BgpLSIdentifierTlv) {
164 newBuilder.set(DOMAIN_IDENTIFIER,
165 Integer.toString(((BgpLSIdentifierTlv) tlv).getBgpLsIdentifier()));
166 }
167 if (tlv.getType() == NodeDescriptors.IGP_ROUTERID_TYPE) {
168 if (tlv instanceof IsIsPseudonode) {
169 deviceType = VIRTUAL;
170 newBuilder.set(AnnotationKeys.ROUTER_ID, new String(((IsIsPseudonode) tlv).getIsoNodeId()));
171 } else if (tlv instanceof OspfPseudonode) {
172 deviceType = VIRTUAL;
173 newBuilder
174 .set(AnnotationKeys.ROUTER_ID, Integer.toString(((OspfPseudonode) tlv).getrouterID()));
175 } else if (tlv instanceof IsIsNonPseudonode) {
176 newBuilder.set(AnnotationKeys.ROUTER_ID, new String(((IsIsNonPseudonode) tlv).getIsoNodeId()));
177 } else if (tlv instanceof OspfNonPseudonode) {
178 newBuilder.set(AnnotationKeys.ROUTER_ID,
179 Integer.toString(((OspfNonPseudonode) tlv).getrouterID()));
180 }
181 }
182 }
183
184 DeviceDescription description = new DefaultDeviceDescription(uri(nodeUri.toString()), deviceType, UNKNOWN,
185 UNKNOWN, UNKNOWN, UNKNOWN, cId, newBuilder.build());
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530186 deviceProviderService.deviceConnected(deviceId, description);
187
188 }
189
190 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530191 public void deleteNode(BgpNodeLSNlriVer4 nodeNlri) {
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530192 log.debug("Delete node {}", nodeNlri.toString());
193
194 if (deviceProviderService == null) {
195 return;
196 }
197
Priyanka Bfc51c952016-03-26 14:30:33 +0530198 BgpDpid deviceUri = new BgpDpid(nodeNlri);
199 DeviceId deviceId = deviceId(uri(deviceUri.toString()));
200 deviceProviderService.deviceDisconnected(deviceId);
201 }
202
203 @Override
204 public void addLink(BgpLinkLsNlriVer4 linkNlri, PathAttrNlriDetails details) throws BgpParseException {
205 log.debug("Addlink {}", linkNlri.toString());
206
207 if (linkProviderService == null) {
208 return;
209 }
210 LinkDescription linkDes = buildLinkDes(linkNlri, details, true);
211 linkProviderService.linkDetected(linkDes);
212 }
213
214 //Build link description.
215 private LinkDescription buildLinkDes(BgpLinkLsNlriVer4 linkNlri, PathAttrNlriDetails details, boolean isAddLink)
216 throws BgpParseException {
217 long srcAddress = 0;
218 long dstAddress = 0;
219 boolean localPseduo = false;
220 boolean remotePseduo = false;
221
222 List<BgpValueType> localTlvs = linkNlri.getLinkIdentifier().localNodeDescriptors().getSubTlvs();
223 for (BgpValueType localTlv : localTlvs) {
224 if (localTlv instanceof IsIsPseudonode || localTlv instanceof OspfPseudonode) {
225 localPseduo = true;
226 }
227 }
228 List<BgpValueType> remoteTlvs = linkNlri.getLinkIdentifier().remoteNodeDescriptors().getSubTlvs();
229 for (BgpValueType remoteTlv : remoteTlvs) {
230 if (remoteTlv instanceof IsIsPseudonode || remoteTlv instanceof OspfPseudonode) {
231 remotePseduo = true;
232 }
233 }
234
235 List<BgpValueType> tlvs = linkNlri.getLinkIdentifier().linkDescriptors();
236 for (BgpValueType tlv : tlvs) {
237 if (tlv instanceof LinkLocalRemoteIdentifiersTlv) {
238 srcAddress = ((LinkLocalRemoteIdentifiersTlv) tlv).getLinkLocalIdentifier();
239 //Set 32nd bit.
240 srcAddress = srcAddress | IDENTIFIER_SET;
241 dstAddress = ((LinkLocalRemoteIdentifiersTlv) tlv).getLinkRemoteIdentifier();
242 dstAddress = dstAddress | IDENTIFIER_SET;
243 } else if (tlv instanceof IPv4AddressTlv) {
244 if (tlv.getType() == BgpLinkLSIdentifier.IPV4_INTERFACE_ADDRESS_TYPE) {
245 srcAddress = ((IPv4AddressTlv) tlv).address().toInt();
246 } else {
247 dstAddress = ((IPv4AddressTlv) tlv).address().toInt();
248 }
249 }
250 }
251
252 DeviceId srcId = deviceId(uri(new BgpDpid(linkNlri, BgpDpid.NODE_DESCRIPTOR_LOCAL).toString()));
253 DeviceId dstId = deviceId(uri(new BgpDpid(linkNlri, BgpDpid.NODE_DESCRIPTOR_REMOTE).toString()));
254
255 if (localPseduo && srcAddress == 0) {
256 srcAddress = PSEUDO_PORT;
257 } else if (remotePseduo && dstAddress == 0) {
258 dstAddress = PSEUDO_PORT;
259 }
260
261 ConnectPoint src = new ConnectPoint(srcId, PortNumber.portNumber(srcAddress));
262 ConnectPoint dst = new ConnectPoint(dstId, PortNumber.portNumber(dstAddress));
263 BgpNodeLSNlriVer4 srcNodeNlri = new BgpNodeLSNlriVer4(linkNlri.getIdentifier(), linkNlri.getProtocolId()
264 .getType(), new BgpNodeLSIdentifier(linkNlri.getLinkIdentifier().localNodeDescriptors()), false,
265 linkNlri.getRouteDistinguisher());
266
267 BgpNodeLSNlriVer4 dstNodeNlri = new BgpNodeLSNlriVer4(linkNlri.getIdentifier(), linkNlri.getProtocolId()
268 .getType(), new BgpNodeLSIdentifier(linkNlri.getLinkIdentifier().remoteNodeDescriptors()), false,
269 linkNlri.getRouteDistinguisher());
270
271 addOrDeletePseudoNode(isAddLink, localPseduo, remotePseduo, srcNodeNlri,
272 dstNodeNlri, srcId, dstId, details);
273 return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false);
274 }
275
276 private void addOrDeletePseudoNode(boolean isAddLink, boolean localPseduo, boolean remotePseduo,
277 BgpNodeLSNlriVer4 srcNodeNlri, BgpNodeLSNlriVer4 dstNodeNlri, DeviceId srcId, DeviceId dstId,
278 PathAttrNlriDetails details) {
279 if (isAddLink) {
280 if (localPseduo) {
281 if (deviceService.getDevice(srcId) == null) {
282 for (BgpNodeListener l : controller.listener()) {
283 l.addNode(srcNodeNlri, details);
284 }
285 }
286 } else if (remotePseduo) {
287 if (deviceService.getDevice(dstId) == null) {
288 for (BgpNodeListener l : controller.listener()) {
289 l.addNode(dstNodeNlri, details);
290 }
291 }
292 }
293 } else {
294 if (localPseduo) {
295 Set<Link> links = linkService.getDeviceLinks(srcId);
296 if (links == null || links.isEmpty()) {
297 for (BgpNodeListener l : controller.listener()) {
298 l.deleteNode(srcNodeNlri);
299 }
300 }
301 } else if (remotePseduo) {
302 log.info("Remote pseudo delete link ");
303 Set<Link> links = linkService.getDeviceLinks(dstId);
304 if (links == null || links.isEmpty()) {
305 for (BgpNodeListener l : controller.listener()) {
306 l.deleteNode(dstNodeNlri);
307 }
308 }
309 }
310 }
311 }
312
313 @Override
314 public void deleteLink(BgpLinkLsNlriVer4 linkNlri) throws BgpParseException {
315 log.debug("Delete link {}", linkNlri.toString());
316
317 if (linkProviderService == null) {
318 return;
319 }
320
321 LinkDescription linkDes = buildLinkDes(linkNlri, null, false);
322 linkProviderService.linkVanished(linkDes);
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530323 }
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530324 }
325
326 @Override
327 public void triggerProbe(DeviceId deviceId) {
328 // TODO Auto-generated method stub
329 }
330
331 @Override
332 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
333 }
334
335 @Override
336 public boolean isReachable(DeviceId deviceId) {
337 // TODO Auto-generated method stub
338 return true;
339 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700340
341 @Override
342 public void changePortState(DeviceId deviceId, PortNumber portNumber,
343 boolean enable) {
344 }
Shashikanth VH1ca26ce2015-11-20 23:19:49 +0530345}