blob: ebb683c682f9ea4553206a2c4d0d93b3999e6bfd [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;
28import org.onosproject.net.driver.AbstractHandlerBehaviour;
29import org.onosproject.net.link.LinkDescription;
30import org.onosproject.netconf.NetconfController;
Yuta HIGUCHI234eaf32017-09-06 13:45:05 -070031import org.onosproject.netconf.NetconfException;
Michele Santuari21c14012016-11-14 13:31:33 +010032import org.onosproject.netconf.NetconfSession;
33import org.slf4j.Logger;
34
Michele Santuari21c14012016-11-14 13:31:33 +010035import java.util.HashSet;
36import java.util.Optional;
37import java.util.Set;
38
39import static com.google.common.base.Preconditions.checkNotNull;
40import static org.onosproject.drivers.juniper.JuniperUtils.LinkAbstraction;
41import static org.onosproject.drivers.juniper.JuniperUtils.parseJuniperLldp;
42import static org.onosproject.drivers.juniper.JuniperUtils.requestBuilder;
Yuta HIGUCHI0184a7b2017-03-31 13:13:58 -070043import static org.onosproject.drivers.utilities.XmlConfigParser.loadXmlString;
Michele Santuari21c14012016-11-14 13:31:33 +010044import static org.onosproject.net.AnnotationKeys.PORT_NAME;
45import static org.onosproject.drivers.juniper.JuniperUtils.REQ_LLDP_NBR_INFO;
Michele Santuari21c14012016-11-14 13:31:33 +010046import static org.slf4j.LoggerFactory.getLogger;
47
48
49/**
50 * Retrieve Links discovered by the device LLDP.
51 * Tested with MX240 junos 14.2
52 */
53@Beta
54public class LinkDiscoveryJuniperImpl extends AbstractHandlerBehaviour
55 implements LinkDiscovery {
56
57 private final Logger log = getLogger(getClass());
58
59 @Override
60 public Set<LinkDescription> getLinks() {
61 DeviceId localDeviceId = this.handler().data().deviceId();
62 NetconfController controller =
63 checkNotNull(handler().get(NetconfController.class));
64 NetconfSession session =
65 controller.getDevicesMap().get(localDeviceId).getSession();
66
67 String reply;
68 try {
69 reply = session.get(requestBuilder(REQ_LLDP_NBR_INFO));
Yuta HIGUCHI234eaf32017-09-06 13:45:05 -070070 } catch (NetconfException e) {
Michele Santuarif5945372017-01-19 16:39:21 +010071 log.warn("Failed to retrieve ports for device {}", localDeviceId);
72 return ImmutableSet.of();
Michele Santuari21c14012016-11-14 13:31:33 +010073 }
74 log.debug("Reply from device {} : {}", localDeviceId, reply);
Yuta HIGUCHI0184a7b2017-03-31 13:13:58 -070075 Set<LinkAbstraction> linkAbstractions = parseJuniperLldp(loadXmlString(reply));
Michele Santuari21c14012016-11-14 13:31:33 +010076 log.debug("Set of LinkAbstraction discovered {}", linkAbstractions);
77
78 DeviceService deviceService = this.handler().get(DeviceService.class);
79 Set<LinkDescription> descriptions = new HashSet<>();
80
81 //for each lldp neighbor create two LinkDescription
82 for (LinkAbstraction linkAbs : linkAbstractions) {
83
84 //find source port by local port name
85 Optional<Port> localPort = deviceService.getPorts(localDeviceId).stream()
86 .filter(port -> {
87 if (linkAbs.localPortName.equals(
88 port.annotations().value(PORT_NAME))) {
89 return true;
90 }
91 return false;
92 }).findAny();
93 if (!localPort.isPresent()) {
94 log.warn("Port name {} does not exist in device {}",
95 linkAbs.localPortName, localDeviceId);
96 continue;
97 }
98 //find destination device by remote chassis id
99 com.google.common.base.Optional<Device> dev = Iterables.tryFind(
100 deviceService.getAvailableDevices(),
101 input -> input.chassisId().equals(linkAbs.remoteChassisId));
102
103 if (!dev.isPresent()) {
104 log.warn("Device with chassis ID {} does not exist",
105 linkAbs.remoteChassisId);
106 continue;
107 }
108 Device remoteDevice = dev.get();
109
110 //find destination port by interface index
111 Optional<Port> remotePort = deviceService.getPorts(remoteDevice.id())
112 .stream().filter(port -> {
donghyeok.hoe6d71872018-07-25 18:57:44 +0900113 if (port.number().toLong() == linkAbs.remotePortIndex) {
114 return true;
115 }
116 if (port.annotations().value(AnnotationKeys.PORT_MAC) != null
117 && linkAbs.remotePortId != null
118 && port.annotations().value(AnnotationKeys.PORT_MAC).equals(linkAbs.remotePortId)) {
119 return true;
120 }
121 if (port.annotations().value(AnnotationKeys.PORT_NAME) != null
122 && linkAbs.remotePortId != null
123 && port.annotations().value(AnnotationKeys.PORT_NAME).equals(linkAbs.remotePortId)) {
124 return true;
125 }
126 if (port.annotations().value(AnnotationKeys.PORT_NAME) != null
127 && linkAbs.remotePortDescription != null
128 && port.annotations().value(AnnotationKeys.PORT_NAME)
129 .equals(linkAbs.remotePortDescription)) {
130 return true;
131 }
132 return false;
133 }).findAny();
Michele Santuari21c14012016-11-14 13:31:33 +0100134 if (!remotePort.isPresent()) {
donghyeok.hoe6d71872018-07-25 18:57:44 +0900135 log.warn("Port Index and Port Id and Port description do not exist in device {}", remoteDevice.id());
Michele Santuari21c14012016-11-14 13:31:33 +0100136 continue;
137 }
138
DongRyeol Cha81935a62018-11-30 16:51:21 +0900139 if (!localPort.get().isEnabled() || !remotePort.get().isEnabled()) {
140 log.debug("Ports are disabled. Cannot create a link between {}/{} and {}/{}",
141 localDeviceId, localPort.get(), remoteDevice.id(), remotePort.get());
142 continue;
143 }
144
DongRyeol Chace65cc02018-07-23 15:02:28 +0900145 JuniperUtils.createOneWayLinkDescription(localDeviceId,
146 localPort.get(),
147 remoteDevice.id(),
148 remotePort.get(),
149 descriptions);
Michele Santuari21c14012016-11-14 13:31:33 +0100150 }
151 return descriptions;
152 }
153}