diff options
Diffstat (limited to 'framework/src/onos/drivers')
5 files changed, 395 insertions, 2 deletions
diff --git a/framework/src/onos/drivers/pom.xml b/framework/src/onos/drivers/pom.xml index 749a68c4..56a39a8e 100644 --- a/framework/src/onos/drivers/pom.xml +++ b/framework/src/onos/drivers/pom.xml @@ -55,8 +55,8 @@ <dependency> <groupId>org.onosproject</groupId> <artifactId>onos-core-serializers</artifactId> - <version>1.4.0-SNAPSHOT</version> - </dependency> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.onosproject</groupId> <artifactId>onos-ovsdb-api</artifactId> @@ -72,6 +72,25 @@ <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.scr.annotations</artifactId> </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-ovsdb-api</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java new file mode 100644 index 00000000..a62b93c8 --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java @@ -0,0 +1,170 @@ +/* + * Copyright 2015 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.driver.handshaker; + +import org.projectfloodlight.openflow.protocol.OFExpPort; +import org.projectfloodlight.openflow.protocol.OFExpPortDescReply; +import org.projectfloodlight.openflow.protocol.OFExpPortDescRequest; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFPortDesc; +import org.projectfloodlight.openflow.protocol.OFStatsReply; +import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags; +import org.projectfloodlight.openflow.protocol.OFStatsType; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; + +import org.onosproject.net.Device; +import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; +import org.onosproject.openflow.controller.PortDescPropertyType; +import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted; +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted; +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted; +import org.projectfloodlight.openflow.protocol.OFObject; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + + +/** + * Open Flow Optical Switch handshaker - for Open Flow 13. + */ +public class OFOpticalSwitch13 extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch { + + private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false); + private List<OFExpPort> expPortDes = new ArrayList<>(); + + @Override + public Boolean supportNxRole() { + return false; + } + + @Override + public void startDriverHandshake() { + log.info("Starting driver handshake for sw {}", getStringId()); + if (startDriverHandshakeCalled) { + throw new SwitchDriverSubHandshakeAlreadyStarted(); + } + startDriverHandshakeCalled = true; + + log.debug("sendHandshakeOFExperimenterPortDescRequest for sw {}", getStringId()); + + try { + sendHandshakeOFExperimenterPortDescRequest(); + } catch (IOException e) { + log.error("Failed to send handshaker message OFExperimenterPortDescRequestfor sw {}, {}", + getStringId(), e.getMessage()); + e.printStackTrace(); + } + } + + @Override + public void processDriverHandshakeMessage(OFMessage m) { + if (!startDriverHandshakeCalled) { + throw new SwitchDriverSubHandshakeNotStarted(); + } + if (driverHandshakeComplete.get()) { + throw new SwitchDriverSubHandshakeCompleted(m); + } + + log.debug("processDriverHandshakeMessage for sw {}", getStringId()); + + switch (m.getType()) { + case STATS_REPLY: // multipart message is reported as STAT + processOFMultipartReply((OFStatsReply) m); + break; + default: + log.warn("Received message {} during switch-driver " + + "subhandshake " + "from switch {} ... " + + "Ignoring message", m, + getStringId()); + } + } + + private void processOFMultipartReply(OFStatsReply stats) { + log.debug("Received message {} during switch-driver " + + "subhandshake " + "from switch {} ... " + + stats, + getStringId()); + + if (stats.getStatsType() == OFStatsType.EXPERIMENTER) { + try { + OFExpPortDescReply expPortDescReply = (OFExpPortDescReply) stats; + expPortDes.addAll(expPortDescReply.getEntries()); + if (!expPortDescReply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { + driverHandshakeComplete.set(true); + return; + } + } catch (ClassCastException e) { + log.error("Unexspected Experimenter Multipart message type {} " + , stats.getClass().getName()); + } + } + } + + + @Override + public boolean isDriverHandshakeComplete() { + return driverHandshakeComplete.get(); + } + + private void sendHandshakeOFExperimenterPortDescRequest() throws + IOException { + + OFExpPortDescRequest preq = factory() + .buildExpPortDescRequest() + .setXid(getNextTransactionId()) + .build(); + + log.debug("Sending experimented port description " + + "message " + + "{}", + preq.toString()); + + this.sendHandshakeMessage(preq); + } + + @Override + public Device.Type deviceType() { + return Device.Type.ROADM; + } + + /* + * OduClt ports are reported as regular ETH ports. + */ + @Override + public List<OFPortDesc> getPorts() { + return ImmutableList.copyOf( + ports.stream().flatMap(p -> p.getEntries().stream()) + .collect(Collectors.toList())); + } + + @Override + public List<? extends OFObject> getPortsOf(PortDescPropertyType type) { + return ImmutableList.copyOf(expPortDes); + } + + @Override + public Set<PortDescPropertyType> getPortTypes() { + return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT); + } + +} diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbControllerConfig.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbControllerConfig.java new file mode 100644 index 00000000..a00d3dbc --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbControllerConfig.java @@ -0,0 +1,102 @@ +/* + * Copyright 2015 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.driver.ovsdb; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.TpPort; +import org.onosproject.net.AnnotationKeys; +import org.onosproject.net.DeviceId; +import org.onosproject.net.behaviour.ControllerConfig; +import org.onosproject.net.behaviour.ControllerInfo; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.driver.AbstractHandlerBehaviour; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.ovsdb.controller.OvsdbBridge; +import org.onosproject.ovsdb.controller.OvsdbClientService; +import org.onosproject.ovsdb.controller.OvsdbController; +import org.onosproject.ovsdb.controller.OvsdbNodeId; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.google.common.base.Preconditions.checkState; +import static org.onlab.util.Tools.delay; + +/** + * Implementation of controller config which allows to get and set controllers. + */ +public class OvsdbControllerConfig extends AbstractHandlerBehaviour implements ControllerConfig { + @Override + public List<ControllerInfo> getControllers() { + DriverHandler handler = handler(); + OvsdbClientService clientService = getOvsdbClientService(handler); + Set<ControllerInfo> controllers = clientService.getControllers( + handler().data().deviceId()); + return new ArrayList<>(controllers); + } + + @Override + public void setControllers(List<ControllerInfo> controllers) { + DriverHandler handler = handler(); + OvsdbClientService clientService = getOvsdbClientService(handler); + if (!clientService.getControllers(handler().data().deviceId()) + .equals(controllers)) { + clientService.setControllersWithDeviceId(handler(). + data().deviceId(), controllers); + } + } + + // Used for getting OvsdbClientService. + private OvsdbClientService getOvsdbClientService(DriverHandler handler) { + OvsdbController ovsController = handler.get(OvsdbController.class); + DeviceService deviceService = handler.get(DeviceService.class); + DeviceId ofDeviceId = handler.data().deviceId(); + String[] mgmtAddress = deviceService.getDevice(ofDeviceId) + .annotations().value(AnnotationKeys.MANAGEMENT_ADDRESS).split(":"); + String targetIp = mgmtAddress[0]; + TpPort targetPort = null; + if (mgmtAddress.length > 1) { + targetPort = TpPort.tpPort(Integer.parseInt(mgmtAddress[1])); + } + + List<OvsdbNodeId> nodeIds = ovsController.getNodeIds().stream() + .filter(nodeId -> nodeId.getIpAddress().equals(targetIp)) + .collect(Collectors.toList()); + if (nodeIds.size() == 0) { + //TODO decide what port? + ovsController.connect(IpAddress.valueOf(targetIp), + targetPort == null ? TpPort.tpPort(6640) : targetPort); + delay(1000); //FIXME... connect is async + } + List<OvsdbClientService> clientServices = ovsController.getNodeIds().stream() + .filter(nodeId -> nodeId.getIpAddress().equals(targetIp)) + .map(ovsController::getOvsdbClient) + .filter(cs -> cs.getBridges().stream().anyMatch(b -> dpidMatches(b, ofDeviceId))) + .collect(Collectors.toList()); + checkState(clientServices.size() > 0, "No clientServices found"); + //FIXME add connection to management address if null --> done ? + return clientServices.size() > 0 ? clientServices.get(0) : null; + } + + private static boolean dpidMatches(OvsdbBridge bridge, DeviceId deviceId) { + String bridgeDpid = "of:" + bridge.datapathId().value(); + String ofDpid = deviceId.toString(); + return bridgeDpid.equals(ofDpid); + } +}
\ No newline at end of file diff --git a/framework/src/onos/drivers/src/main/resources/onos-drivers.xml b/framework/src/onos/drivers/src/main/resources/onos-drivers.xml index ac307c28..5059d4bf 100644 --- a/framework/src/onos/drivers/src/main/resources/onos-drivers.xml +++ b/framework/src/onos/drivers/src/main/resources/onos-drivers.xml @@ -30,6 +30,8 @@ manufacturer="Nicira, Inc\." hwVersion="Open vSwitch" swVersion="2\..*"> <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" impl="org.onosproject.driver.handshaker.NiciraSwitchHandshaker"/> + <behaviour api="org.onosproject.net.behaviour.ControllerConfig" + impl="org.onosproject.driver.ovsdb.OvsdbControllerConfig"/> </driver> <driver name="ovs-corsa" extends="ovs" manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0"> @@ -120,5 +122,10 @@ <behaviour api="org.onosproject.net.behaviour.Pipeliner" impl="org.onosproject.driver.pipeline.OpenVSwitchPipeline"/> </driver> + <driver name="eci" extends="default" + manufacturer="ECI Telecom" hwVersion="optical" swVersion="V_1_0"> + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" + impl="org.onosproject.driver.handshaker.OFOpticalSwitch13"/> + </driver> </drivers> diff --git a/framework/src/onos/drivers/src/test/java/org/onosproject/driver/ovsdb/OvsdbControllerConfigTest.java b/framework/src/onos/drivers/src/test/java/org/onosproject/driver/ovsdb/OvsdbControllerConfigTest.java new file mode 100644 index 00000000..4a91efcd --- /dev/null +++ b/framework/src/onos/drivers/src/test/java/org/onosproject/driver/ovsdb/OvsdbControllerConfigTest.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015 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.driver.ovsdb; + +import com.google.common.collect.ImmutableMap; +import org.junit.Before; +import org.junit.Test; +import org.onosproject.net.DeviceId; +import org.onosproject.net.behaviour.ControllerConfig; +import org.onosproject.net.device.DeviceServiceAdapter; +import org.onosproject.net.driver.DefaultDriver; +import org.onosproject.net.driver.DefaultDriverData; +import org.onosproject.net.driver.DefaultDriverHandler; +import org.onosproject.ovsdb.controller.driver.OvsdbClientServiceAdapter; +import org.onosproject.ovsdb.controller.driver.OvsdbControllerAdapter; + +/** + * Created by Andrea on 10/7/15. + */ +public class OvsdbControllerConfigTest { + + + private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo"); + + private DefaultDriver ddc; + private DefaultDriverData data; + private DefaultDriverHandler handler; + + private TestDeviceService deviceService = new TestDeviceService(); + private TestOvsdbController controller = new TestOvsdbController(); + private TestOvsdbClient client = new TestOvsdbClient(); + + private OvsdbControllerConfig controllerConfig; + + + @Before + public void setUp() { + controllerConfig = new OvsdbControllerConfig(); + + ddc = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a", + ImmutableMap.of(ControllerConfig.class, + OvsdbControllerConfig.class), + ImmutableMap.of("foo", "bar")); + data = new DefaultDriverData(ddc, DEVICE_ID); + handler = new DefaultDriverHandler(data); + //handler.controllerConfig.setHandler(handler); + //TODO setTestService directory on handler + //TODO setup ovsdb fake controller with fake ovsdbclient + //TODO setup fake device service + } + + @Test + public void testGetControllers() throws Exception { +// DriverService driverService = new Driv +// AbstractBehaviour ab = new AbstractBehaviour(); +// DriverHandler handler = handler(); +// List<ControllerInfo> controllersList = +// controllerConfig.getControllers(DeviceId.deviceId("0000000000000018")); +// log.info("controllers " + controllersList); + + } + + @Test + public void testSetControllers() throws Exception { + + } + + + private class TestDeviceService extends DeviceServiceAdapter { + + } + + private class TestOvsdbController extends OvsdbControllerAdapter { + + + } + + private class TestOvsdbClient extends OvsdbClientServiceAdapter { + + } +}
\ No newline at end of file |