diff --git a/drivers/juniper/BUCK b/drivers/juniper/BUCK new file mode 100644 index 0000000000..1a40781033 --- /dev/null +++ b/drivers/juniper/BUCK @@ -0,0 +1,26 @@ +COMPILE_DEPS = [ + '//lib:CORE_DEPS', + '//drivers/utilities:onos-drivers-utilities', + '//protocols/netconf/api:onos-protocols-netconf-api', +] + +BUNDLES = [ + ':onos-drivers-juniper', + '//drivers/utilities:onos-drivers-utilities', +] + +osgi_jar_with_tests ( + deps = COMPILE_DEPS, + resources_root = 'src/main/resources', + resources = glob(['src/main/resources/**']), +) + +onos_app ( + app_name = 'org.onosproject.drivers.juniper', + title = 'Juniper Device Drivers', + category = 'Drivers', + url = 'http://onosproject.org', + description = 'ONOS Juniper Device Drivers application.', + included_bundles = BUNDLES, + required_apps = [ 'org.onosproject.netconf' ], +) \ No newline at end of file diff --git a/drivers/juniper/features.xml b/drivers/juniper/features.xml new file mode 100644 index 0000000000..c367eb54cf --- /dev/null +++ b/drivers/juniper/features.xml @@ -0,0 +1,35 @@ + + + + + + + onos-api + + mvn:${project.groupId}/${project.artifactId}/${project.version} + + + + mvn:${project.groupId}/onos-drivers-utilities/${project.version} + + + mvn:${project.groupId}/onos-netconf-api/${project.version} + + + diff --git a/drivers/juniper/pom.xml b/drivers/juniper/pom.xml new file mode 100644 index 0000000000..7b9e06accd --- /dev/null +++ b/drivers/juniper/pom.xml @@ -0,0 +1,49 @@ + + + + + + onos-drivers-general + org.onosproject + 1.8.0-SNAPSHOT + + 4.0.0 + + Juniper device drivers + + + org.onosproject + onos-netconf-api + ${project.version} + + + org.onosproject + onos-drivers-utilities + ${project.version} + + + + onos-drivers-juniper + bundle + + + org.onosproject.drivers.juniper + + + \ No newline at end of file diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/DeviceDiscoveryJuniperImpl.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/DeviceDiscoveryJuniperImpl.java new file mode 100644 index 0000000000..e277d7edc5 --- /dev/null +++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/DeviceDiscoveryJuniperImpl.java @@ -0,0 +1,89 @@ +/* + * Copyright 2016 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.drivers.juniper; + + +import com.google.common.annotations.Beta; +import org.onosproject.drivers.utilities.XmlConfigParser; +import org.onosproject.net.DeviceId; +import org.onosproject.net.device.DeviceDescription; +import org.onosproject.net.device.DeviceDescriptionDiscovery; +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.driver.AbstractHandlerBehaviour; +import org.onosproject.netconf.NetconfController; +import org.onosproject.netconf.NetconfException; +import org.onosproject.netconf.NetconfSession; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.drivers.juniper.JuniperUtils.FAILED_CFG; +import static org.onosproject.drivers.juniper.JuniperUtils.REQ_IF_INFO; +import static org.onosproject.drivers.juniper.JuniperUtils.REQ_MAC_ADD_INFO; +import static org.onosproject.drivers.juniper.JuniperUtils.REQ_SYS_INFO; +import static org.onosproject.drivers.juniper.JuniperUtils.requestBuilder; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Retrieve the Device information and ports via NETCONF for Juniper Router. + * Tested with MX240 junos 14.2 + */ +@Beta +public class DeviceDiscoveryJuniperImpl extends AbstractHandlerBehaviour + implements DeviceDescriptionDiscovery { + + public final org.slf4j.Logger log = getLogger(getClass()); + + @Override + public DeviceDescription discoverDeviceDetails() { + DeviceId deviceId = handler().data().deviceId(); + NetconfController controller = checkNotNull(handler().get(NetconfController.class)); + NetconfSession session = controller.getDevicesMap().get(deviceId).getSession(); + String sysInfo; + String chassis; + try { + sysInfo = session.get(requestBuilder(REQ_SYS_INFO)); + chassis = session.get(requestBuilder(REQ_MAC_ADD_INFO)); + } catch (IOException e) { + throw new RuntimeException(new NetconfException(FAILED_CFG, e)); + } + DeviceDescription description = + JuniperUtils.parseJuniperDescription(deviceId, XmlConfigParser. + loadXml(new ByteArrayInputStream(sysInfo.getBytes())), chassis); + log.debug("Device description {}", description); + return description; + } + + @Override + public List discoverPortDetails() { + NetconfController controller = checkNotNull(handler().get(NetconfController.class)); + NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession(); + String reply; + try { + reply = session.get(requestBuilder(REQ_IF_INFO)); + } catch (IOException e) { + throw new RuntimeException(new NetconfException(FAILED_CFG, e)); + } + List descriptions = + JuniperUtils.parseJuniperPorts(XmlConfigParser. + loadXml(new ByteArrayInputStream(reply.getBytes()))); + log.debug("Discovered ports {}", descriptions); + return descriptions; + } +} diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperDriversLoader.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperDriversLoader.java new file mode 100644 index 0000000000..85c3408ab3 --- /dev/null +++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperDriversLoader.java @@ -0,0 +1,27 @@ +/* + * Copyright 2016 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.drivers.juniper; + +import org.apache.felix.scr.annotations.Component; +import org.onosproject.net.driver.AbstractDriverLoader; + +@Component(immediate = true) +public class JuniperDriversLoader extends AbstractDriverLoader { + public JuniperDriversLoader() { + super("/juniper-drivers.xml"); + } +} diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java new file mode 100644 index 0000000000..7d771cbc2a --- /dev/null +++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java @@ -0,0 +1,339 @@ +/* + * Copyright 2016-present Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.drivers.juniper; + +import com.google.common.collect.Lists; +import org.apache.commons.configuration.HierarchicalConfiguration; +import org.onlab.packet.ChassisId; +import org.onlab.packet.MacAddress; +import org.onosproject.net.AnnotationKeys; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DefaultAnnotations; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Link; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.device.DefaultDeviceDescription; +import org.onosproject.net.device.DefaultPortDescription; +import org.onosproject.net.device.DeviceDescription; +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.link.DefaultLinkDescription; +import org.onosproject.net.link.LinkDescription; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.lang.Integer.parseInt; +import static org.onosproject.net.DefaultAnnotations.Builder; +import static org.onosproject.net.Device.Type.ROUTER; +import static org.onosproject.net.Port.Type.COPPER; +import static org.onosproject.net.PortNumber.portNumber; + +/** + * Utility class for Netconf XML for Juniper. + * Tested with MX240 junos 14.2 + */ +public final class JuniperUtils { + + public static final String FAILED_CFG = "Failed to retrieve configuration."; + + private static final String RPC_TAG_NETCONF_BASE = ""; + private static final String RPC_CLOSE_TAG = ""; + + //requests + public static final String REQ_LLDP_NBR_INFO = ""; + public static final String REQ_SYS_INFO = ""; + public static final String REQ_MAC_ADD_INFO = ""; + public static final String REQ_IF_INFO = ""; + + //helper strings for parsing + private static final String LLDP_NBR_INFO = "lldp-neighbors-information"; + private static final String SYS_INFO = "system-information"; + private static final String HW_MODEL = "hardware-model"; + private static final String OS_NAME = "os-name"; + private static final String OS_VER = "os-version"; + private static final String SER_NUM = "serial-number"; + private static final String IF_INFO = "interface-information"; + private static final String IF_PHY = "physical-interface"; + private static final String IF_TYPE = "if-type"; + private static final String SPEED = "speed"; + private static final String ETH = "Ethernet"; + private static final String MBPS = "mbps"; + private static final String NAME = "name"; + private static final String IF_LO_ENCAP = "logical-interface.encapsulation"; + private static final String IF_LO_NAME = "logical-interface.name"; + private static final String IF_LO_ADD = + "logical-interface.address-family.interface-address.ifa-local"; + private static final String LO_INDEX = "local-index"; + private static final String STATUS = "admin-status"; + private static final String SNMP_INDEX = "snmp-index"; + private static final String IF_LO_INDEX = "logical-interface.local-index"; + private static final String IF_LO_STATUS = + "logical-interface.if-config-flags.iff-up"; + private static final String LLDP_LO_PORT = "lldp-local-port-id"; + private static final String LLDP_REM_CHASS = "lldp-remote-chassis-id"; + private static final String LLDP_REM_PORT = "lldp-remote-port-id"; + private static final String REGEX_ADD = + ".*Private base address\\s*([:,0-9,a-f,A-F]*).*"; + private static final Pattern ADD_PATTERN = + Pattern.compile(REGEX_ADD, Pattern.DOTALL); + + private static final String JUNIPER = "JUNIPER"; + private static final String UNKNOWN = "UNKNOWN"; + private static final long DEFAULT_PORT_SPEED = 1000; + + + private JuniperUtils() { + //not called, preventing any allocation + } + + /** + * Helper method to build a XML schema given a request. + * + * @param request a tag element of the XML schema + * @return string containing the XML schema + */ + public static String requestBuilder(String request) { + return RPC_TAG_NETCONF_BASE + + request + RPC_CLOSE_TAG; + } + + /** + * Parses device configuration and returns the device description. + * + * @param deviceId the id of the device + * @param sysInfoCfg system configuration + * @param chassisText chassis string + * @return device description + */ + public static DeviceDescription parseJuniperDescription(DeviceId deviceId, + HierarchicalConfiguration sysInfoCfg, + String chassisText) { + HierarchicalConfiguration info = sysInfoCfg.configurationAt(SYS_INFO); + + String hw = info.getString(HW_MODEL) == null ? UNKNOWN : info.getString(HW_MODEL); + String sw = UNKNOWN; + if (info.getString(OS_NAME) != null || info.getString(OS_VER) != null) { + sw = info.getString(OS_NAME) + " " + info.getString(OS_VER); + } + String serial = info.getString(SER_NUM) == null ? UNKNOWN : info.getString(SER_NUM); + + Matcher matcher = ADD_PATTERN.matcher(chassisText); + if (matcher.lookingAt()) { + String chassis = matcher.group(1); + MacAddress chassisMac = MacAddress.valueOf(chassis); + return new DefaultDeviceDescription(deviceId.uri(), ROUTER, + JUNIPER, hw, sw, serial, + new ChassisId(chassisMac.toLong()), + DefaultAnnotations.EMPTY); + } + return new DefaultDeviceDescription(deviceId.uri(), ROUTER, + JUNIPER, hw, sw, serial, + null, DefaultAnnotations.EMPTY); + } + + /** + * Parses device ports configuration and returns a list of + * port description. + * + * @param cfg interface configuration + * @return list of interface descriptions of the device + */ + public static List parseJuniperPorts(HierarchicalConfiguration cfg) { + //This methods ignores some internal ports + + List portDescriptions = Lists.newArrayList(); + List subtrees = + cfg.configurationsAt(IF_INFO); + for (HierarchicalConfiguration interfInfo : subtrees) { + List interfaceTree = + interfInfo.configurationsAt(IF_PHY); + for (HierarchicalConfiguration interf : interfaceTree) { + if (interf != null) { + if (interf.getString(IF_TYPE) != null && + interf.getString(SPEED) != null) { + if (interf.getString(IF_TYPE).contains(ETH) && + interf.getString(SPEED).contains(MBPS)) { + portDescriptions.add(parseDefaultPort(interf)); + } + } else if (interf.getString(IF_LO_ENCAP) != null && + !interf.getString(NAME).contains("pfe") && + interf.getString(IF_LO_ENCAP).contains("ENET2")) { + portDescriptions.add(parseLogicalPort(interf)); + } else if (interf.getString(NAME).contains("lo")) { + portDescriptions.add(parseLoopback(interf)); + } + } + } + } + return portDescriptions; + } + + private static PortDescription parseLoopback(HierarchicalConfiguration cfg) { + String name = cfg.getString(IF_LO_NAME).trim(); + PortNumber portNumber = portNumber(name.replace("lo0.", "")); + + Builder annotationsBuilder = DefaultAnnotations.builder() + .set(AnnotationKeys.PORT_NAME, name); + String ip = cfg.getString(IF_LO_ADD); + if (ip != null) { + annotationsBuilder.set("ip", ip); + } + + return new DefaultPortDescription(portNumber, + true, + COPPER, + DEFAULT_PORT_SPEED, + annotationsBuilder.build()); + } + + private static DefaultPortDescription parseDefaultPort(HierarchicalConfiguration cfg) { + PortNumber portNumber = portNumber(cfg.getString(LO_INDEX)); + boolean enabled = cfg.getString(STATUS).equals("up"); + int speed = parseInt(cfg.getString(SPEED).replaceAll(MBPS, "")); + + + Builder annotationsBuilder = DefaultAnnotations.builder() + .set(AnnotationKeys.PORT_NAME, cfg.getString(NAME).trim()); + setIpIfPresent(cfg, annotationsBuilder); + + return new DefaultPortDescription(portNumber, + enabled, + COPPER, + speed, + annotationsBuilder.build()); + } + + private static DefaultPortDescription parseLogicalPort(HierarchicalConfiguration cfg) { + + String name = cfg.getString(NAME).trim(); + String index = cfg.getString(SNMP_INDEX).trim(); + Builder annotationsBuilder = DefaultAnnotations.builder() + .set(AnnotationKeys.PORT_NAME, name) + .set("index", index); + setIpIfPresent(cfg, annotationsBuilder); + + PortNumber portNumber = portNumberFromName(cfg.getString(IF_LO_INDEX), name); + + boolean enabled = false; + if (cfg.getString(IF_LO_STATUS) != null) { + enabled = true; + } + //FIXME: port speed should be exposed + return new DefaultPortDescription( + portNumber, + enabled, + COPPER, + DEFAULT_PORT_SPEED, + annotationsBuilder.build()); + } + + private static PortNumber portNumberFromName(String ifIndex, String name) { + PortNumber portNumber = portNumber(ifIndex); + if (name.contains("-")) { + String[] splitted = name.split("-"); + String typeInt = "[" + splitted[0] + "]"; + String number = splitted[1].replace("/", ""); + number = "(" + number + ")"; + portNumber = PortNumber.fromString(typeInt + number); + } + return portNumber; + } + + private static void setIpIfPresent(HierarchicalConfiguration cfg, + Builder annotationsBuilder) { + String ip = cfg.getString(IF_LO_ADD); + if (ip != null) { + annotationsBuilder.set("ip", ip); + } + } + + /** + * Create two LinkDescriptions corresponding to the bidirectional links. + * + * @param localDevId the identity of the local device + * @param localPort the port of the local device + * @param remoteDevId the identity of the remote device + * @param remotePort the port of the remote device + * @param descs the collection to which the link descriptions + * should be added + */ + public static void createBiDirLinkDescription(DeviceId localDevId, + Port localPort, + DeviceId remoteDevId, + Port remotePort, + Set descs) { + + ConnectPoint local = new ConnectPoint(localDevId, localPort.number()); + ConnectPoint remote = new ConnectPoint(remoteDevId, remotePort.number()); + DefaultAnnotations annotations = DefaultAnnotations.builder() + .set("layer", "IP") + .build(); + descs.add(new DefaultLinkDescription( + local, remote, Link.Type.INDIRECT, false, annotations)); + descs.add(new DefaultLinkDescription( + remote, local, Link.Type.INDIRECT, false, annotations)); + } + + /** + * Parses neighbours discovery information and returns a list of + * link abstractions. + * + * @param info interface configuration + * @return set of link abstractions + */ + public static Set parseJuniperLldp(HierarchicalConfiguration info) { + Set neighbour = new HashSet<>(); + List subtrees = + info.configurationsAt(LLDP_NBR_INFO); + for (HierarchicalConfiguration neighborsInfo : subtrees) { + List neighbors = + neighborsInfo.configurationsAt(LLDP_NBR_INFO); + for (HierarchicalConfiguration neighbor : neighbors) { + String localPortName = neighbor.getString(LLDP_LO_PORT); + MacAddress mac = MacAddress.valueOf( + neighbor.getString(LLDP_REM_CHASS)); + int remotePortIndex = + neighbor.getInt(LLDP_REM_PORT); + LinkAbstraction link = new LinkAbstraction( + localPortName, + mac.toLong(), + remotePortIndex); + neighbour.add(link); + } + } + return neighbour; + } + + /** + * Device representation of the adjacency at the IP Layer. + */ + protected static final class LinkAbstraction { + protected String localPortName; + protected ChassisId remoteChassisId; + protected int remotePortIndex; + + protected LinkAbstraction(String pName, long chassisId, int pIndex) { + this.localPortName = pName; + this.remoteChassisId = new ChassisId(chassisId); + this.remotePortIndex = pIndex; + } + } +} diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java new file mode 100644 index 0000000000..ba346d5838 --- /dev/null +++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java @@ -0,0 +1,138 @@ +/* + * Copyright 2016-present Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.drivers.juniper; + +//import com.google.common.base.Optional; + +import com.google.common.annotations.Beta; +import com.google.common.collect.Iterables; +import org.onosproject.drivers.utilities.XmlConfigParser; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.behaviour.LinkDiscovery; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.driver.AbstractHandlerBehaviour; +import org.onosproject.net.link.LinkDescription; +import org.onosproject.netconf.NetconfController; +import org.onosproject.netconf.NetconfException; +import org.onosproject.netconf.NetconfSession; +import org.slf4j.Logger; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.drivers.juniper.JuniperUtils.LinkAbstraction; +import static org.onosproject.drivers.juniper.JuniperUtils.parseJuniperLldp; +import static org.onosproject.drivers.juniper.JuniperUtils.requestBuilder; +import static org.onosproject.net.AnnotationKeys.PORT_NAME; +import static org.onosproject.drivers.juniper.JuniperUtils.REQ_LLDP_NBR_INFO; +import static org.onosproject.drivers.juniper.JuniperUtils.FAILED_CFG; +import static org.slf4j.LoggerFactory.getLogger; + + +/** + * Retrieve Links discovered by the device LLDP. + * Tested with MX240 junos 14.2 + */ +@Beta +public class LinkDiscoveryJuniperImpl extends AbstractHandlerBehaviour + implements LinkDiscovery { + + private final Logger log = getLogger(getClass()); + + @Override + public Set getLinks() { + DeviceId localDeviceId = this.handler().data().deviceId(); + NetconfController controller = + checkNotNull(handler().get(NetconfController.class)); + NetconfSession session = + controller.getDevicesMap().get(localDeviceId).getSession(); + + String reply; + try { + reply = session.get(requestBuilder(REQ_LLDP_NBR_INFO)); + } catch (IOException e) { + throw new RuntimeException(new NetconfException(FAILED_CFG, e)); + } + log.debug("Reply from device {} : {}", localDeviceId, reply); + Set linkAbstractions = parseJuniperLldp( + XmlConfigParser.loadXml(new ByteArrayInputStream(reply.getBytes()))); + log.debug("Set of LinkAbstraction discovered {}", linkAbstractions); + + DeviceService deviceService = this.handler().get(DeviceService.class); + Set descriptions = new HashSet<>(); + + //for each lldp neighbor create two LinkDescription + for (LinkAbstraction linkAbs : linkAbstractions) { + + //find source port by local port name + Optional localPort = deviceService.getPorts(localDeviceId).stream() + .filter(port -> { + if (linkAbs.localPortName.equals( + port.annotations().value(PORT_NAME))) { + return true; + } + return false; + }).findAny(); + if (!localPort.isPresent()) { + log.warn("Port name {} does not exist in device {}", + linkAbs.localPortName, localDeviceId); + continue; + } + //find destination device by remote chassis id + com.google.common.base.Optional dev = Iterables.tryFind( + deviceService.getAvailableDevices(), + input -> input.chassisId().equals(linkAbs.remoteChassisId)); + + if (!dev.isPresent()) { + log.warn("Device with chassis ID {} does not exist", + linkAbs.remoteChassisId); + continue; + } + Device remoteDevice = dev.get(); + + //find destination port by interface index + Optional remotePort = deviceService.getPorts(remoteDevice.id()) + .stream().filter(port -> { + if (port.annotations().value("index") != null && + Integer.parseInt(port.annotations().value("index")) + == linkAbs.remotePortIndex) { + return true; + } + return false; + }).findAny(); + if (!remotePort.isPresent()) { + log.warn("Port with index {} does not exist in device {}", + linkAbs.remotePortIndex, remoteDevice.id()); + continue; + } + + JuniperUtils.createBiDirLinkDescription(localDeviceId, + localPort.get(), + remoteDevice.id(), + remotePort.get(), + descriptions); + + } + return descriptions; + } +} diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/package-info.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/package-info.java new file mode 100644 index 0000000000..0dfbb33a02 --- /dev/null +++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +/** + * Package for juniper device drivers. + */ +package org.onosproject.drivers.juniper; diff --git a/drivers/juniper/src/main/resources/juniper-drivers.xml b/drivers/juniper/src/main/resources/juniper-drivers.xml new file mode 100644 index 0000000000..a4b1150b3d --- /dev/null +++ b/drivers/juniper/src/main/resources/juniper-drivers.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/drivers/pom.xml b/drivers/pom.xml index 2902441876..5c8204d970 100644 --- a/drivers/pom.xml +++ b/drivers/pom.xml @@ -45,6 +45,7 @@ corsa optical arista + juniper