Marc De Leenheer
Committed by Gerrit Code Review

SNMP based device and flow rule provider for Lumentum SDN ROADMs.

ONOS-3690 and ONOS-3842

Change-Id: If00ba70fa26e01924c225596c52a5ffb24987cc2
Showing 24 changed files with 777 additions and 51 deletions
......@@ -29,7 +29,7 @@ public interface ConfigGetter extends HandlerBehaviour {
/**
* Returns the string representation of a device configuration, returns a
* failure string if the configuration cannot be retreived.
* failure string if the configuration cannot be retrieved.
* @param type the type of configuration to get (i.e. running).
* @return string representation of the configuration or an error string.
*/
......
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ 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.
-->
<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
<feature name="${project.artifactId}" version="${project.version}"
description="${project.description}">
<feature>onos-api</feature>
<bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
<bundle>mvn:${project.groupId}/onos-restsb-api/${project.version}</bundle>
<bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.snmp4j/2.3.4_1</bundle>
</feature>
</features>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>onos-drivers-general</artifactId>
<groupId>org.onosproject</groupId>
<version>1.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>onos-drivers-lumentum</artifactId>
<packaging>bundle</packaging>
<description>Lumentum device drivers</description>
<properties>
<onos.app.name>org.onosproject.drivers.lumentum</onos.app.name>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.snmp4j</artifactId>
<version>2.3.4_1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/*
* 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.lumentum;
import org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.FlowRule;
/**
* Interface for cross connects as common in optical networking.
*/
public interface CrossConnect extends FlowRule {
/**
* Returns the add/drop port of the cross connect.
*
* @return port number
*/
PortNumber addDrop();
/**
* Returns the wavelength of the cross connect.
*
* @return OCh signal
*/
OchSignal ochSignal();
/**
* Returns true if cross connect is adding traffic.
*
* @return true if add rule, false if drop rule
*/
boolean isAddRule();
}
/*
* 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.lumentum;
import org.apache.commons.lang3.tuple.Pair;
import org.onosproject.net.flow.FlowId;
/**
* Simple interface to cache flow ID and priority of cross connect flows.
*/
interface CrossConnectCache {
/**
* Returns the flow ID and priority corresponding to the flow hash.
*
* @param hash flow hash
* @return flow ID and priority, null if not in cache
*/
Pair<FlowId, Integer> get(int hash);
/**
* Stores the flow ID and priority corresponding to the flow hash.
*
* @param hash flow hash
* @param flowId flow ID
* @param priority flow priority
*/
void set(int hash, FlowId flowId, int priority);
/**
* Removes the given hash from the cache.
*
* @param hash flow hash
*/
void remove(int hash);
}
/*
* 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.lumentum;
import org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.OchSignalCriterion;
import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Cross connect abstraction based on a flow rule.
*/
public class CrossConnectFlowRule extends DefaultFlowRule implements CrossConnect {
private PortNumber addDrop;
private OchSignal ochSignal;
private boolean isAddRule;
public CrossConnectFlowRule(FlowRule rule, List<PortNumber> linePorts) {
super(rule);
Set<Criterion> criteria = rule.selector().criteria();
List<Instruction> instructions = rule.treatment().immediate();
// Proper cross connect has criteria for input port, OChSignal and OCh signal type.
// Instruction must be output to port.
checkArgument(criteria.size() == 3, "Wrong size of flow rule criteria for cross connect.");
checkArgument(instructions.size() == 1, "Wrong size of flow rule instructions for cross connect.");
// FIXME: Ensure criteria has exactly one of each match type
criteria.forEach(
c -> checkArgument(c instanceof OchSignalCriterion ||
c instanceof OchSignalTypeCriterion ||
c instanceof PortCriterion,
"Incompatible flow rule criteria for cross connect: " + criteria
)
);
checkArgument(instructions.get(0).type() == Instruction.Type.OUTPUT,
"Incompatible flow rule instructions for cross connect: " + instructions);
ochSignal = criteria.stream()
.filter(c -> c instanceof OchSignalCriterion)
.map(c -> ((OchSignalCriterion) c).lambda())
.findAny()
.orElse(null);
// Add or drop rule?
Instructions.OutputInstruction outInstruction = (Instructions.OutputInstruction) instructions.get(0);
if (linePorts.contains(outInstruction.port())) {
addDrop = criteria.stream()
.filter(c -> c instanceof PortCriterion)
.map(c -> ((PortCriterion) c).port())
.findAny()
.orElse(null);
isAddRule = true;
} else {
addDrop = outInstruction.port();
isAddRule = false;
}
}
@Override
public PortNumber addDrop() {
return addDrop;
}
@Override
public OchSignal ochSignal() {
return ochSignal;
}
@Override
public boolean isAddRule() {
return isAddRule;
}
}
/*
* 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.lumentum;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.net.flow.FlowId;
import java.util.HashMap;
import java.util.Map;
@Component(immediate = true, enabled = true)
@Service
public class DefaultCrossConnectCache implements CrossConnectCache {
private final Map<Integer, Pair<FlowId, Integer>> cache = new HashMap<>();
@Override
public Pair<FlowId, Integer> get(int hash) {
return cache.get(hash);
}
@Override
public void set(int hash, FlowId flowId, int priority) {
cache.put(hash, Pair.of(flowId, priority));
}
@Override
public void remove(int hash) {
cache.remove(hash);
}
}
/*
* 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.lumentum;
import org.onlab.util.Frequency;
import org.onlab.util.Spectrum;
import org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.LambdaQuery;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Implementation of lambda query interface for Lumentum SDN ROADMs.
*
* Device supports 96 wavelengths of 50 GHz, between center frequencies 191.350 THz and 196.075 THz.
*/
public class LambdaQueryLumentumRoadm extends AbstractHandlerBehaviour implements LambdaQuery {
private static final int LAMBDA_COUNT = 96;
@Override
public Set<OchSignal> queryLambdas(PortNumber port) {
int startMultiplier = (int) (LumentumSnmpDevice.START_CENTER_FREQ.subtract(Spectrum.CENTER_FREQUENCY).asHz()
/ Frequency.ofGHz(50).asHz());
return IntStream.range(0, LAMBDA_COUNT)
.mapToObj(x -> new OchSignal(LumentumSnmpDevice.GRID_TYPE,
LumentumSnmpDevice.CHANNEL_SPACING,
startMultiplier + x,
4))
.collect(Collectors.toSet());
}
}
/*
* 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.lumentum;
import org.apache.felix.scr.annotations.Component;
import org.onosproject.net.driver.AbstractDriverLoader;
/**
* Loader for Lumentum device drivers from specific xml.
*/
@Component(immediate = true)
public class LumentumDriversLoader extends AbstractDriverLoader {
public LumentumDriversLoader() {
super("/lumentum-drivers.xml");
}
}
/*
* 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.lumentum;
import com.google.common.base.Preconditions;
import org.onlab.util.Frequency;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.DeviceId;
import org.onosproject.net.GridType;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;
import org.snmp4j.util.TreeEvent;
import org.snmp4j.util.TreeUtils;
import java.io.IOException;
import java.util.List;
/**
* Quick and dirty device abstraction for SNMP-based Lumentum devices.
*
* TODO: Refactor once SnmpDevice is finished
*/
public class LumentumSnmpDevice {
private static final int MAX_SIZE_RESPONSE_PDU = 65535;
private static final int MAX_REPETITIONS = 50; // Only 42 directed ports on our devices
public static final GridType GRID_TYPE = GridType.DWDM;
public static final ChannelSpacing CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ;
public static final Frequency START_CENTER_FREQ = Frequency.ofGHz(191_350);
public static final Frequency END_CENTER_FREQ = Frequency.ofGHz(196_100);
// Lumentum SDN ROADM has shifted channel plan.
// Channel 36 corresponds to ITU-T center frequency, which has spacing multiplier 0.
public static final int MULTIPLIER_SHIFT = 36;
private Snmp snmp;
private CommunityTarget target;
public LumentumSnmpDevice(DeviceId did) throws IOException {
String[] deviceComponents = did.toString().split(":");
Preconditions.checkArgument(deviceComponents.length > 1);
String ipAddress = deviceComponents[1];
String port = deviceComponents[2];
Address targetAddress = GenericAddress.parse("udp:" + ipAddress + "/" + port);
TransportMapping transport = new DefaultUdpTransportMapping();
transport.listen();
snmp = new Snmp(transport);
// setting up target
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setAddress(targetAddress);
target.setRetries(3);
target.setTimeout(1000 * 3);
target.setVersion(SnmpConstants.version2c);
target.setMaxSizeRequestPDU(MAX_SIZE_RESPONSE_PDU);
}
public ResponseEvent set(PDU pdu) throws IOException {
return snmp.set(pdu, target);
}
public List<TreeEvent> get(OID oid) {
TreeUtils treeUtils = new TreeUtils(snmp, new DefaultPDUFactory());
treeUtils.setMaxRepetitions(MAX_REPETITIONS);
return treeUtils.getSubtree(target, oid);
}
}
/*
* 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.lumentum;
import com.google.common.collect.Lists;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.behaviour.PortDiscovery;
import org.onosproject.net.device.OmsPortDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.slf4j.Logger;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.util.TreeEvent;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Discovers the ports of a Lumentum SDN ROADM device using SNMP.
*/
public class PortDiscoveryLumentumRoadm extends AbstractHandlerBehaviour
implements PortDiscovery {
private final Logger log = getLogger(PortDiscoveryLumentumRoadm.class);
private static final String CTRL_PORT_STATE = ".1.3.6.1.4.1.46184.1.4.1.1.3.";
private LumentumSnmpDevice snmp;
@Override
public List<PortDescription> getPorts() {
try {
snmp = new LumentumSnmpDevice(handler().data().deviceId());
} catch (IOException e) {
log.error("Failed to connect to device: ", e);
return Collections.emptyList();
}
List<PortDescription> ports = Lists.newLinkedList();
OID[] oids = {
new OID(CTRL_PORT_STATE + "1"),
new OID(CTRL_PORT_STATE + "2")
};
for (OID oid : oids) {
for (TreeEvent event : snmp.get(oid)) {
if (event != null) {
VariableBinding[] varBindings = event.getVariableBindings();
for (VariableBinding varBinding : varBindings) {
if (varBinding.getVariable().toInt() == 1) {
int portNumber = varBinding.getOid().removeLast();
int portDirection = varBinding.getOid().removeLast();
SparseAnnotations ann = DefaultAnnotations.builder()
.set(AnnotationKeys.PORT_NAME, portDirection + "-" + portNumber)
.build();
PortDescription p = new OmsPortDescription(
PortNumber.portNumber(ports.size() + 1),
true,
LumentumSnmpDevice.START_CENTER_FREQ,
LumentumSnmpDevice.END_CENTER_FREQ,
LumentumSnmpDevice.CHANNEL_SPACING.frequency(),
ann);
ports.add(p);
}
}
}
}
}
// Create LINE IN and LINE OUT ports as these are not reported through SNMP
SparseAnnotations annLineIn = DefaultAnnotations.builder()
.set(AnnotationKeys.PORT_NAME, "LINE IN")
.build();
ports.add(new OmsPortDescription(
PortNumber.portNumber(ports.size() + 1),
true,
LumentumSnmpDevice.START_CENTER_FREQ,
LumentumSnmpDevice.END_CENTER_FREQ,
LumentumSnmpDevice.CHANNEL_SPACING.frequency(),
annLineIn
));
SparseAnnotations annLineOut = DefaultAnnotations.builder()
.set(AnnotationKeys.PORT_NAME, "LINE OUT")
.build();
ports.add(new OmsPortDescription(
PortNumber.portNumber(ports.size() + 1),
true,
LumentumSnmpDevice.START_CENTER_FREQ,
LumentumSnmpDevice.END_CENTER_FREQ,
LumentumSnmpDevice.CHANNEL_SPACING.frequency(),
annLineOut
));
return ports;
}
}
/*
* 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 Lumentum device drivers.
*/
package org.onosproject.drivers.lumentum;
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<drivers>
<driver name="lumentum" manufacturer="Lumentum" hwVersion="SDN ROADM" swVersion="1.0">
<behaviour api="org.onosproject.net.behaviour.PortDiscovery"
impl="org.onosproject.drivers.lumentum.PortDiscoveryLumentumRoadm"/>
<behaviour api="org.onosproject.net.behaviour.LambdaQuery"
impl="org.onosproject.drivers.lumentum.LambdaQueryLumentumRoadm"/>
<behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
impl="org.onosproject.drivers.lumentum.LumentumFlowRuleDriver"/>
</driver>
</drivers>
......@@ -58,7 +58,7 @@ public class NetconfControllerConfig extends AbstractHandlerBehaviour
controllers.addAll(XmlConfigParser.parseStreamControllers(XmlConfigParser.
loadXml(new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8)))));
} catch (IOException e) {
log.error("Cannot comunicate to device {} ", ofDeviceId);
log.error("Cannot communicate with device {} ", ofDeviceId);
}
return controllers;
}
......
......@@ -39,6 +39,7 @@
<module>netconf</module>
<module>ovsdb</module>
<module>utilities</module>
<module>lumentum</module>
</modules>
<!--<properties>
......
......@@ -16,8 +16,6 @@
package org.onosproject.openflow.controller.driver;
import static org.onlab.util.Tools.groupedThreads;
import com.google.common.collect.Lists;
import org.jboss.netty.channel.Channel;
import org.onlab.packet.IpAddress;
......@@ -26,23 +24,21 @@ import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.RoleState;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFExperimenter;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFExperimenter;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFRoleRequest;
import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleRequest;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFRoleReply;
import org.projectfloodlight.openflow.protocol.OFRoleRequest;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -60,6 +56,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.onlab.util.Tools.groupedThreads;
/**
* An abstract representation of an OpenFlow switch. Can be extended by others
* to serve as a base for their vendor specific representation of a switch.
......@@ -200,7 +198,8 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
}
@Override
public final void sendHandshakeMessage(OFMessage message) {
public final void
sendHandshakeMessage(OFMessage message) {
if (!this.isDriverHandshakeComplete()) {
sendMsgsOnChannel(Collections.singletonList(message));
}
......
......@@ -15,24 +15,10 @@
*/
package org.onosproject.provider.of.device.impl;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.util.Tools.get;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Port.Type.COPPER;
import static org.onosproject.net.Port.Type.FIBER;
import static org.onosproject.openflow.controller.Dpid.dpid;
import static org.onosproject.openflow.controller.Dpid.uri;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -82,6 +68,8 @@ import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.PortDescPropertyType;
import org.onosproject.openflow.controller.RoleState;
import org.osgi.service.component.ComponentContext;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescProp;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescPropOptical;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsEntry;
import org.projectfloodlight.openflow.protocol.OFExpPort;
import org.projectfloodlight.openflow.protocol.OFExpPortDescPropOpticalTransport;
......@@ -108,10 +96,23 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.types.PortSpeed;
import org.slf4j.Logger;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.util.Tools.get;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Port.Type.COPPER;
import static org.onosproject.net.Port.Type.FIBER;
import static org.onosproject.openflow.controller.Dpid.dpid;
import static org.onosproject.openflow.controller.Dpid.uri;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Provider which uses an OpenFlow controller to detect network
......@@ -691,9 +692,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
private PortDescription buildPortDescription(OFCalientPortDescStatsEntry port) {
PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
// Use the alias name if it's available
String name = port.getName();
List<OFCalientPortDescProp> props = port.getProperties();
if (props != null && props.size() > 0) {
OFCalientPortDescPropOptical propOptical = (OFCalientPortDescPropOptical) props.get(0);
if (propOptical != null) {
name = propOptical.getInAlias();
}
}
// FIXME when Calient OF agent reports port status
boolean enabled = true;
SparseAnnotations annotations = makePortAnnotation(port.getName(), port.getHwAddr().toString());
SparseAnnotations annotations = makePortAnnotation(name, port.getHwAddr().toString());
// S160 data sheet
// Wavelength range: 1260 - 1630 nm, grid is irrelevant for this type of switch
......
......@@ -19,14 +19,16 @@ import com.btisystems.pronx.ems.core.model.ClassRegistry;
import com.btisystems.pronx.ems.core.model.IClassRegistry;
import com.btisystems.pronx.ems.core.model.NetworkDevice;
import com.btisystems.pronx.ems.core.snmp.ISnmpSession;
import java.io.IOException;
import java.util.Arrays;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
import org.snmp4j.smi.OID;
import java.io.IOException;
import java.util.Arrays;
import static org.slf4j.LoggerFactory.getLogger;
/**
* A vendor-specific implementation supporting BTI Systems BTI-7000 equipment.
* @deprecated 1.5.0 Falcon, not compliant with ONOS SB and driver architecture.
......@@ -55,7 +57,7 @@ public class Bti7000DeviceDescriptionProvider implements SnmpDeviceDescriptionPr
String[] systemComponents = systemTree.getSysDescr().split(";");
return new DefaultDeviceDescription(description.deviceUri(), description.type(),
systemComponents[0], systemComponents[2], systemComponents[3],
UNKNOWN, description.chassisId());
UNKNOWN, description.chassisId(), description.annotations());
}
} catch (IOException ex) {
log.error("Error reading details for device {}.", session.getAddress(), ex);
......
/*
* 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.provider.snmp.device.impl;
import com.btisystems.pronx.ems.core.snmp.ISnmpSession;
import org.onosproject.net.Device;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Device description provider for Lumentum SDN ROADMs.
* @deprecated 1.5.0 Falcon, not compliant with ONOS SB and driver architecture.
*/
@Deprecated
public class LumentumDeviceDescriptionProvider implements SnmpDeviceDescriptionProvider {
private static final Logger log = LoggerFactory.getLogger(LumentumDeviceDescriptionProvider.class);
@Override
public DeviceDescription populateDescription(ISnmpSession session, DeviceDescription description) {
return new DefaultDeviceDescription(description.deviceUri(), Device.Type.ROADM,
"Lumentum", "SDN ROADM", "1.0", "v1", description.chassisId(), description.annotations());
}
}
......@@ -19,15 +19,17 @@ import com.btisystems.pronx.ems.core.model.ClassRegistry;
import com.btisystems.pronx.ems.core.model.IClassRegistry;
import com.btisystems.pronx.ems.core.model.NetworkDevice;
import com.btisystems.pronx.ems.core.snmp.ISnmpSession;
import java.io.IOException;
import java.util.Arrays;
import org.apache.commons.lang.StringUtils;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
import org.snmp4j.smi.OID;
import java.io.IOException;
import java.util.Arrays;
import static org.slf4j.LoggerFactory.getLogger;
/**
* A agent-specific implementation supporting NET-SNMP agents.
* @deprecated 1.5.0 Falcon, not compliant with ONOS SB and driver architecture.
......@@ -57,7 +59,7 @@ public class NetSnmpDeviceDescriptionProvider implements SnmpDeviceDescriptionPr
// so cut it here until supported in prop displayer
String manufacturer = StringUtils.abbreviate(systemTree.getSysContact(), 20);
return new DefaultDeviceDescription(description.deviceUri(), description.type(), manufacturer,
UNKNOWN, UNKNOWN, UNKNOWN, description.chassisId());
UNKNOWN, UNKNOWN, UNKNOWN, description.chassisId(), description.annotations());
}
} catch (IOException ex) {
log.error("Error reading details for device {}.", session.getAddress(), ex);
......
......@@ -32,5 +32,4 @@ public interface SnmpDeviceDescriptionProvider {
*/
@Deprecated
DeviceDescription populateDescription(ISnmpSession session, DeviceDescription description);
}
......
......@@ -32,9 +32,13 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.ChassisId;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.cluster.ClusterService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.behaviour.PortDiscovery;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
......@@ -120,6 +124,7 @@ public class SnmpDeviceProvider extends AbstractProvider
//TODO refactor, no hardcoding in provider, device information should be in drivers
providers.put("1.3.6.1.4.1.18070.2.2", new Bti7000DeviceDescriptionProvider());
providers.put("1.3.6.1.4.1.20408", new NetSnmpDeviceDescriptionProvider());
providers.put("1.3.6.1.4.562.73.6", new LumentumDeviceDescriptionProvider());
}
@Activate
......@@ -341,9 +346,12 @@ public class SnmpDeviceProvider extends AbstractProvider
DeviceId did = getDeviceId();
ChassisId cid = new ChassisId();
SparseAnnotations annotations = DefaultAnnotations.builder()
.set(AnnotationKeys.PROTOCOL, SCHEME.toUpperCase())
.build();
DeviceDescription desc = new DefaultDeviceDescription(
did.uri(), Device.Type.OTHER, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, cid);
did.uri(), Device.Type.OTHER, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, cid, annotations);
desc = populateDescriptionFromDevice(did, desc);
......@@ -353,6 +361,18 @@ public class SnmpDeviceProvider extends AbstractProvider
providerService.deviceConnected(did, desc);
log.info("Done with Device Info Creation on ONOS core. Device Info: "
+ device.deviceInfo() + " " + did.uri().toString());
// Do port discovery if driver supports it
Device d = deviceService.getDevice(did);
if (d.is(PortDiscovery.class)) {
PortDiscovery portConfig = d.as(PortDiscovery.class);
if (portConfig != null) {
providerService.updatePorts(did, portConfig.getPorts());
}
} else {
log.warn("No port discovery behaviour for device {}", did);
}
delay(EVENTINTERVAL);
} catch (URISyntaxException e) {
log.error("Syntax Error while creating URI for the device: "
......@@ -373,8 +393,8 @@ public class SnmpDeviceProvider extends AbstractProvider
String ipAddress = deviceComponents[1];
String port = deviceComponents[2];
ISnmpConfiguration config = new V2cSnmpConfiguration();
config.setPort(Integer.parseInt(port));
ISnmpConfiguration config = new V2cSnmpConfiguration();
config.setPort(Integer.parseInt(port));
try (ISnmpSession session = sessionFactory.createSession(config, ipAddress)) {
// Each session will be auto-closed.
......
#
# devices which support SNMP, these may support SNMP fault-management.
# demo.snmplabs.com is a publically available SNMP agent-simulator accessible via the internet, see http://snmpsim.sourceforge.net/public-snmp-simulator.html
......