blob: 441def00cc72c977b87df82ab5ea1606bc990f1c [file] [log] [blame]
Michele Santuari21c14012016-11-14 13:31:33 +01001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Michele Santuari21c14012016-11-14 13:31:33 +01003 *
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.drivers.juniper;
18
Michele Santuari21c14012016-11-14 13:31:33 +010019import com.google.common.annotations.Beta;
Michele Santuarif5945372017-01-19 16:39:21 +010020import com.google.common.collect.ImmutableSet;
Michele Santuari21c14012016-11-14 13:31:33 +010021import com.google.common.collect.Iterables;
donghyeok.ho82749aa2018-07-16 19:57:03 +090022import org.onosproject.net.AnnotationKeys;
Michele Santuari21c14012016-11-14 13:31:33 +010023import org.onosproject.net.Device;
24import org.onosproject.net.DeviceId;
25import org.onosproject.net.Port;
26import org.onosproject.net.behaviour.LinkDiscovery;
27import org.onosproject.net.device.DeviceService;
Michele Santuari21c14012016-11-14 13:31:33 +010028import org.onosproject.net.link.LinkDescription;
Yuta HIGUCHI234eaf32017-09-06 13:45:05 -070029import org.onosproject.netconf.NetconfException;
Michele Santuari21c14012016-11-14 13:31:33 +010030import org.onosproject.netconf.NetconfSession;
31import org.slf4j.Logger;
32
Michele Santuari21c14012016-11-14 13:31:33 +010033import java.util.HashSet;
34import java.util.Optional;
35import java.util.Set;
36
Michele Santuari21c14012016-11-14 13:31:33 +010037import static org.onosproject.drivers.juniper.JuniperUtils.LinkAbstraction;
38import static org.onosproject.drivers.juniper.JuniperUtils.parseJuniperLldp;
39import static org.onosproject.drivers.juniper.JuniperUtils.requestBuilder;
Yuta HIGUCHI0184a7b2017-03-31 13:13:58 -070040import static org.onosproject.drivers.utilities.XmlConfigParser.loadXmlString;
Michele Santuari21c14012016-11-14 13:31:33 +010041import static org.onosproject.net.AnnotationKeys.PORT_NAME;
42import static org.onosproject.drivers.juniper.JuniperUtils.REQ_LLDP_NBR_INFO;
Michele Santuari21c14012016-11-14 13:31:33 +010043import static org.slf4j.LoggerFactory.getLogger;
44
45
46/**
47 * Retrieve Links discovered by the device LLDP.
48 * Tested with MX240 junos 14.2
49 */
50@Beta
Kieran McPeake9e64ab52019-06-07 10:22:29 +010051public class LinkDiscoveryJuniperImpl extends JuniperAbstractHandlerBehaviour
Michele Santuari21c14012016-11-14 13:31:33 +010052 implements LinkDiscovery {
53
54 private final Logger log = getLogger(getClass());
55
56 @Override
57 public Set<LinkDescription> getLinks() {
58 DeviceId localDeviceId = this.handler().data().deviceId();
Kieran McPeake9e64ab52019-06-07 10:22:29 +010059 NetconfSession session = lookupNetconfSession(localDeviceId);
Michele Santuari21c14012016-11-14 13:31:33 +010060
61 String reply;
62 try {
63 reply = session.get(requestBuilder(REQ_LLDP_NBR_INFO));
Yuta HIGUCHI234eaf32017-09-06 13:45:05 -070064 } catch (NetconfException e) {
Kieran McPeakee1b418f2019-05-23 13:42:13 +010065 log.warn("Failed to retrieve lldp-neighbors-information for device {}", localDeviceId);
Michele Santuarif5945372017-01-19 16:39:21 +010066 return ImmutableSet.of();
Michele Santuari21c14012016-11-14 13:31:33 +010067 }
68 log.debug("Reply from device {} : {}", localDeviceId, reply);
Yuta HIGUCHI0184a7b2017-03-31 13:13:58 -070069 Set<LinkAbstraction> linkAbstractions = parseJuniperLldp(loadXmlString(reply));
Michele Santuari21c14012016-11-14 13:31:33 +010070 log.debug("Set of LinkAbstraction discovered {}", linkAbstractions);
71
72 DeviceService deviceService = this.handler().get(DeviceService.class);
73 Set<LinkDescription> descriptions = new HashSet<>();
74
75 //for each lldp neighbor create two LinkDescription
76 for (LinkAbstraction linkAbs : linkAbstractions) {
77
78 //find source port by local port name
79 Optional<Port> localPort = deviceService.getPorts(localDeviceId).stream()
Kieran McPeake201fe1f2019-06-03 12:47:22 +010080 .filter(port -> linkAbs.localPortName.equals(
81 port.annotations().value(PORT_NAME))).findAny();
Michele Santuari21c14012016-11-14 13:31:33 +010082 if (!localPort.isPresent()) {
83 log.warn("Port name {} does not exist in device {}",
84 linkAbs.localPortName, localDeviceId);
85 continue;
86 }
87 //find destination device by remote chassis id
88 com.google.common.base.Optional<Device> dev = Iterables.tryFind(
89 deviceService.getAvailableDevices(),
90 input -> input.chassisId().equals(linkAbs.remoteChassisId));
91
92 if (!dev.isPresent()) {
Kieran McPeakee1b418f2019-05-23 13:42:13 +010093 log.warn("Device with chassis ID {} does not exist. Referenced by {}/{}",
94 linkAbs.remoteChassisId, localDeviceId, linkAbs);
Michele Santuari21c14012016-11-14 13:31:33 +010095 continue;
96 }
97 Device remoteDevice = dev.get();
98
99 //find destination port by interface index
100 Optional<Port> remotePort = deviceService.getPorts(remoteDevice.id())
101 .stream().filter(port -> {
donghyeok.hoe6d71872018-07-25 18:57:44 +0900102 if (port.number().toLong() == linkAbs.remotePortIndex) {
103 return true;
104 }
105 if (port.annotations().value(AnnotationKeys.PORT_MAC) != null
106 && linkAbs.remotePortId != null
107 && port.annotations().value(AnnotationKeys.PORT_MAC).equals(linkAbs.remotePortId)) {
108 return true;
109 }
110 if (port.annotations().value(AnnotationKeys.PORT_NAME) != null
111 && linkAbs.remotePortId != null
112 && port.annotations().value(AnnotationKeys.PORT_NAME).equals(linkAbs.remotePortId)) {
113 return true;
114 }
115 if (port.annotations().value(AnnotationKeys.PORT_NAME) != null
116 && linkAbs.remotePortDescription != null
117 && port.annotations().value(AnnotationKeys.PORT_NAME)
118 .equals(linkAbs.remotePortDescription)) {
119 return true;
120 }
121 return false;
122 }).findAny();
Michele Santuari21c14012016-11-14 13:31:33 +0100123 if (!remotePort.isPresent()) {
Kieran McPeakee1b418f2019-05-23 13:42:13 +0100124 log.warn("Port does not exist in remote device {}. Referenced by {}/{}",
125 remoteDevice.id(), localDeviceId, linkAbs);
Michele Santuari21c14012016-11-14 13:31:33 +0100126 continue;
127 }
128
DongRyeol Cha81935a62018-11-30 16:51:21 +0900129 if (!localPort.get().isEnabled() || !remotePort.get().isEnabled()) {
130 log.debug("Ports are disabled. Cannot create a link between {}/{} and {}/{}",
131 localDeviceId, localPort.get(), remoteDevice.id(), remotePort.get());
132 continue;
133 }
134
DongRyeol Chace65cc02018-07-23 15:02:28 +0900135 JuniperUtils.createOneWayLinkDescription(localDeviceId,
136 localPort.get(),
137 remoteDevice.id(),
138 remotePort.get(),
139 descriptions);
Michele Santuari21c14012016-11-14 13:31:33 +0100140 }
141 return descriptions;
142 }
143}