mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-05 12:16:13 +02:00
SNMP based device and flow rule provider for Lumentum SDN ROADMs.
ONOS-3690 and ONOS-3842 Change-Id: If00ba70fa26e01924c225596c52a5ffb24987cc2
This commit is contained in:
parent
842283b4f9
commit
c662d328f2
@ -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.
|
||||
*/
|
||||
|
||||
28
drivers/lumentum/features.xml
Normal file
28
drivers/lumentum/features.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?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>
|
||||
43
drivers/lumentum/pom.xml
Normal file
43
drivers/lumentum/pom.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?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>
|
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 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.apache.commons.lang3.tuple.Pair;
|
||||
import org.onosproject.net.ChannelSpacing;
|
||||
import org.onosproject.net.GridType;
|
||||
import org.onosproject.net.OchSignal;
|
||||
import org.onosproject.net.OchSignalType;
|
||||
import org.onosproject.net.Port;
|
||||
import org.onosproject.net.PortNumber;
|
||||
import org.onosproject.net.device.DeviceService;
|
||||
import org.onosproject.net.driver.AbstractHandlerBehaviour;
|
||||
import org.onosproject.net.flow.DefaultFlowEntry;
|
||||
import org.onosproject.net.flow.DefaultFlowRule;
|
||||
import org.onosproject.net.flow.DefaultTrafficSelector;
|
||||
import org.onosproject.net.flow.DefaultTrafficTreatment;
|
||||
import org.onosproject.net.flow.FlowEntry;
|
||||
import org.onosproject.net.flow.FlowId;
|
||||
import org.onosproject.net.flow.FlowRule;
|
||||
import org.onosproject.net.flow.FlowRuleProgrammable;
|
||||
import org.onosproject.net.flow.TrafficSelector;
|
||||
import org.onosproject.net.flow.TrafficTreatment;
|
||||
import org.onosproject.net.flow.criteria.Criteria;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.smi.Integer32;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.UnsignedInteger32;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
import org.snmp4j.util.TreeEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
// TODO: need to convert between OChSignal and XC channel number
|
||||
public class LumentumFlowRuleDriver extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
|
||||
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(LumentumFlowRuleDriver.class);
|
||||
private static final int DEFAULT_ATTENUATION = 160;
|
||||
private static final int OUT_OF_SERVICE = 1;
|
||||
private static final int IN_SERVICE = 2;
|
||||
private static final String CTRL_AMP_MODULE_SERVICE_STATE_PREAMP = ".1.3.6.1.4.1.46184.1.4.4.1.2.1";
|
||||
private static final String CTRL_AMP_MODULE_SERVICE_STATE_BOOSTER = ".1.3.6.1.4.1.46184.1.4.4.1.2.2";
|
||||
private static final String CTRL_CHANNEL_STATE = ".1.3.6.1.4.1.46184.1.4.2.1.3.";
|
||||
private static final String CTRL_CHANNEL_ADD_DROP_PORT_INDEX = ".1.3.6.1.4.1.46184.1.4.2.1.13.";
|
||||
private static final String CTRL_CHANNEL_ABSOLUTE_ATTENUATION = ".1.3.6.1.4.1.46184.1.4.2.1.5.";
|
||||
|
||||
private LumentumSnmpDevice snmp;
|
||||
|
||||
@Override
|
||||
public Collection<FlowEntry> getFlowEntries() {
|
||||
try {
|
||||
snmp = new LumentumSnmpDevice(handler().data().deviceId());
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to connect to device: ", e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// Line in is last but one port, line out is last
|
||||
DeviceService deviceService = this.handler().get(DeviceService.class);
|
||||
List<Port> ports = deviceService.getPorts(data().deviceId());
|
||||
if (ports.size() < 2) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
PortNumber lineIn = ports.get(ports.size() - 2).number();
|
||||
PortNumber lineOut = ports.get(ports.size() - 1).number();
|
||||
|
||||
Collection<FlowEntry> entries = Lists.newLinkedList();
|
||||
|
||||
// Add rules
|
||||
OID addOid = new OID(CTRL_CHANNEL_STATE + "1");
|
||||
entries.addAll(
|
||||
fetchRules(addOid, true, lineOut).stream()
|
||||
.map(fr -> new DefaultFlowEntry(fr, FlowEntry.FlowEntryState.ADDED, 0, 0, 0))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
// Drop rules
|
||||
OID dropOid = new OID(CTRL_CHANNEL_STATE + "2");
|
||||
entries.addAll(
|
||||
fetchRules(dropOid, false, lineIn).stream()
|
||||
.map(fr -> new DefaultFlowEntry(fr, FlowEntry.FlowEntryState.ADDED, 0, 0, 0))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
|
||||
try {
|
||||
snmp = new LumentumSnmpDevice(data().deviceId());
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to connect to device: ", e);
|
||||
}
|
||||
|
||||
// Line ports
|
||||
DeviceService deviceService = this.handler().get(DeviceService.class);
|
||||
List<Port> ports = deviceService.getPorts(data().deviceId());
|
||||
List<PortNumber> linePorts = ports.subList(ports.size() - 2, ports.size()).stream()
|
||||
.map(p -> p.number())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Apply the valid rules on the device
|
||||
Collection<FlowRule> added = rules.stream()
|
||||
.map(r -> new CrossConnectFlowRule(r, linePorts))
|
||||
.filter(xc -> installCrossConnect(xc))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Cache the cookie/priority
|
||||
CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
|
||||
added.stream()
|
||||
.forEach(xc -> cache.set(
|
||||
Objects.hash(data().deviceId(), xc.selector(), xc.treatment()),
|
||||
xc.id(),
|
||||
xc.priority()));
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
|
||||
try {
|
||||
snmp = new LumentumSnmpDevice(data().deviceId());
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to connect to device: ", e);
|
||||
}
|
||||
|
||||
// Line ports
|
||||
DeviceService deviceService = this.handler().get(DeviceService.class);
|
||||
List<Port> ports = deviceService.getPorts(data().deviceId());
|
||||
List<PortNumber> linePorts = ports.subList(ports.size() - 2, ports.size()).stream()
|
||||
.map(p -> p.number())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Apply the valid rules on the device
|
||||
Collection<FlowRule> removed = rules.stream()
|
||||
.map(r -> new CrossConnectFlowRule(r, linePorts))
|
||||
.filter(xc -> removeCrossConnect(xc))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Remove flow rule from cache
|
||||
CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
|
||||
removed.stream()
|
||||
.forEach(xc -> cache.remove(
|
||||
Objects.hash(data().deviceId(), xc.selector(), xc.treatment())));
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
// Installs cross connect on device
|
||||
private boolean installCrossConnect(CrossConnectFlowRule xc) {
|
||||
|
||||
int channel = toChannel(xc.ochSignal());
|
||||
long addDrop = xc.addDrop().toLong();
|
||||
|
||||
// Create the PDU object
|
||||
PDU pdu = new PDU();
|
||||
pdu.setType(PDU.SET);
|
||||
|
||||
// Enable preamp & booster for service
|
||||
List<OID> oids = Arrays.asList(new OID(CTRL_AMP_MODULE_SERVICE_STATE_PREAMP),
|
||||
new OID(CTRL_AMP_MODULE_SERVICE_STATE_BOOSTER));
|
||||
oids.forEach(
|
||||
oid -> pdu.add(new VariableBinding(oid, new Integer32(IN_SERVICE)))
|
||||
);
|
||||
|
||||
// Enable the channel
|
||||
OID ctrlChannelState = new OID(CTRL_CHANNEL_STATE + (xc.isAddRule() ? "1." : "2.") + channel);
|
||||
pdu.add(new VariableBinding(ctrlChannelState, new Integer32(IN_SERVICE)));
|
||||
|
||||
// Make cross connect
|
||||
OID ctrlChannelAddDropPortIndex = new OID(CTRL_CHANNEL_ADD_DROP_PORT_INDEX +
|
||||
(xc.isAddRule() ? "1." : "2.") + channel);
|
||||
pdu.add(new VariableBinding(ctrlChannelAddDropPortIndex, new UnsignedInteger32(addDrop)));
|
||||
|
||||
// Set attenuation to zero
|
||||
OID ctrlChannelAbsoluteAttenuation = new OID(CTRL_CHANNEL_ABSOLUTE_ATTENUATION +
|
||||
(xc.isAddRule() ? "1." : "2.") + channel);
|
||||
pdu.add(new VariableBinding(ctrlChannelAbsoluteAttenuation, new UnsignedInteger32(0)));
|
||||
|
||||
try {
|
||||
ResponseEvent response = snmp.set(pdu);
|
||||
|
||||
// TODO: parse response
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to create cross connect, unable to connect to device: ", e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Removes cross connect on device
|
||||
private boolean removeCrossConnect(CrossConnectFlowRule xc) {
|
||||
|
||||
int channel = toChannel(xc.ochSignal());
|
||||
|
||||
// Create the PDU object
|
||||
PDU pdu = new PDU();
|
||||
pdu.setType(PDU.SET);
|
||||
|
||||
// Disable the channel
|
||||
OID ctrlChannelState = new OID(CTRL_CHANNEL_STATE + (xc.isAddRule() ? "1." : "2.") + channel);
|
||||
pdu.add(new VariableBinding(ctrlChannelState, new Integer32(OUT_OF_SERVICE)));
|
||||
|
||||
// Put cross connect back into default port 1
|
||||
OID ctrlChannelAddDropPortIndex = new OID(CTRL_CHANNEL_ADD_DROP_PORT_INDEX +
|
||||
(xc.isAddRule() ? "1." : "2.") + channel);
|
||||
pdu.add(new VariableBinding(ctrlChannelAddDropPortIndex, new UnsignedInteger32(OUT_OF_SERVICE)));
|
||||
|
||||
// Set attenuation to default value
|
||||
OID ctrlChannelAbsoluteAttenuation = new OID(CTRL_CHANNEL_ABSOLUTE_ATTENUATION +
|
||||
(xc.isAddRule() ? "1." : "2.") + channel);
|
||||
pdu.add(new VariableBinding(ctrlChannelAbsoluteAttenuation, new UnsignedInteger32(DEFAULT_ATTENUATION))
|
||||
);
|
||||
|
||||
try {
|
||||
ResponseEvent response = snmp.set(pdu);
|
||||
|
||||
// TODO: parse response
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to remove cross connect, unable to connect to device: ", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert OCh signal to Lumentum channel ID.
|
||||
*
|
||||
* @param ochSignal OCh signal
|
||||
* @return Lumentum channel ID
|
||||
*/
|
||||
public static int toChannel(OchSignal ochSignal) {
|
||||
// FIXME: move to cross connect validation
|
||||
checkArgument(ochSignal.channelSpacing() == ChannelSpacing.CHL_50GHZ);
|
||||
checkArgument(LumentumSnmpDevice.START_CENTER_FREQ.compareTo(ochSignal.centralFrequency()) <= 0);
|
||||
checkArgument(LumentumSnmpDevice.END_CENTER_FREQ.compareTo(ochSignal.centralFrequency()) >= 0);
|
||||
|
||||
return ochSignal.spacingMultiplier() + LumentumSnmpDevice.MULTIPLIER_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Lumentum channel ID to OCh signal.
|
||||
*
|
||||
* @param channel Lumentum channel ID
|
||||
* @return OCh signal
|
||||
*/
|
||||
public static OchSignal toOchSignal(int channel) {
|
||||
checkArgument(1 <= channel);
|
||||
checkArgument(channel <= 96);
|
||||
|
||||
return new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ,
|
||||
channel - LumentumSnmpDevice.MULTIPLIER_SHIFT, 4);
|
||||
}
|
||||
|
||||
// Returns the currently configured add/drop port for the given channel.
|
||||
private PortNumber getAddDropPort(int channel, boolean isAddPort) {
|
||||
OID oid = new OID(CTRL_CHANNEL_ADD_DROP_PORT_INDEX + (isAddPort ? "1" : "2"));
|
||||
|
||||
for (TreeEvent event : snmp.get(oid)) {
|
||||
if (event == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
VariableBinding[] varBindings = event.getVariableBindings();
|
||||
|
||||
for (VariableBinding varBinding : varBindings) {
|
||||
if (varBinding.getOid().last() == channel) {
|
||||
int port = varBinding.getVariable().toInt();
|
||||
return PortNumber.portNumber(port);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns the currently installed flow entries on the device.
|
||||
private List<FlowRule> fetchRules(OID oid, boolean isAdd, PortNumber linePort) {
|
||||
List<FlowRule> rules = new LinkedList<>();
|
||||
|
||||
for (TreeEvent event : snmp.get(oid)) {
|
||||
if (event == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VariableBinding[] varBindings = event.getVariableBindings();
|
||||
for (VariableBinding varBinding : varBindings) {
|
||||
CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
|
||||
|
||||
if (varBinding.getVariable().toInt() == IN_SERVICE) {
|
||||
int channel = varBinding.getOid().removeLast();
|
||||
|
||||
PortNumber addDropPort = getAddDropPort(channel, isAdd);
|
||||
if (addDropPort == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TrafficSelector selector = DefaultTrafficSelector.builder()
|
||||
.matchInPort(isAdd ? addDropPort : linePort)
|
||||
.add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
|
||||
.add(Criteria.matchLambda(toOchSignal(channel)))
|
||||
.build();
|
||||
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
|
||||
.setOutput(isAdd ? linePort : addDropPort)
|
||||
.build();
|
||||
|
||||
// Lookup flow ID and priority
|
||||
int hash = Objects.hash(data().deviceId(), selector, treatment);
|
||||
Pair<FlowId, Integer> lookup = cache.get(hash);
|
||||
if (lookup == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FlowRule fr = DefaultFlowRule.builder()
|
||||
.forDevice(data().deviceId())
|
||||
.makePermanent()
|
||||
.withSelector(selector)
|
||||
.withTreatment(treatment)
|
||||
.withPriority(lookup.getRight())
|
||||
.withCookie(lookup.getLeft().value())
|
||||
.build();
|
||||
rules.add(fr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rules;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 Lumentum device drivers.
|
||||
*/
|
||||
package org.onosproject.drivers.lumentum;
|
||||
27
drivers/lumentum/src/main/resources/lumentum-drivers.xml
Normal file
27
drivers/lumentum/src/main/resources/lumentum-drivers.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<?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.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.OFPortStatus;
|
||||
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.OFMessage;
|
||||
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.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);
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
#
|
||||
# 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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user