moving openflow drivers to their own bundle
Change-Id: Ie38dc932fdf23112cafc0fa5d0d7693a5023e16c
diff --git a/openflow/ctl/pom.xml b/openflow/ctl/pom.xml
index 07572e4..b459ca8 100644
--- a/openflow/ctl/pom.xml
+++ b/openflow/ctl/pom.xml
@@ -36,6 +36,11 @@
<artifactId>onos-of-api</artifactId>
</dependency>
<dependency>
+ <groupId>org.onlab.onos</groupId>
+ <artifactId>onos-of-drivers</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
</dependency>
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/controller/impl/Controller.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/controller/impl/Controller.java
index 1d0e4cb..bf97d0a 100644
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/controller/impl/Controller.java
+++ b/openflow/ctl/src/main/java/org/onlab/onos/openflow/controller/impl/Controller.java
@@ -31,7 +31,7 @@
import org.onlab.onos.openflow.controller.Dpid;
import org.onlab.onos.openflow.controller.driver.OpenFlowAgent;
import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
-import org.onlab.onos.openflow.drivers.impl.DriverManager;
+import org.onlab.onos.openflow.drivers.DriverManager;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFactory;
@@ -201,7 +201,7 @@
protected OpenFlowSwitchDriver getOFSwitchInstance(long dpid,
OFDescStatsReply desc, OFVersion ofv) {
OpenFlowSwitchDriver sw = DriverManager.getSwitch(new Dpid(dpid),
- desc, ofv);
+ desc, ofv);
sw.setAgent(agent);
sw.setRoleHandler(new RoleManager(sw));
return sw;
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/DriverManager.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/DriverManager.java
deleted file mode 100644
index 5af0a64..0000000
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/DriverManager.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright 2014 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.onlab.onos.openflow.drivers.impl;
-
-
-
-import java.util.Collections;
-import java.util.List;
-
-import org.onlab.onos.openflow.controller.Dpid;
-import org.onlab.onos.openflow.controller.RoleState;
-import org.onlab.onos.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
-import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriverFactory;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A simple implementation of a driver manager that differentiates between
- * connected switches using the OF Description Statistics Reply message.
- */
-public final class DriverManager implements OpenFlowSwitchDriverFactory {
-
- private static final Logger log = LoggerFactory.getLogger(DriverManager.class);
-
- // Whether to use an OF 1.3 configured TTP, or to use an OF 1.0-style
- // single table with packet-ins.
- private static boolean cpqdUsePipeline13 = false;
-
- /**
- * Return an IOFSwitch object based on switch's manufacturer description
- * from OFDescStatsReply.
- *
- * @param desc DescriptionStatistics reply from the switch
- * @return A IOFSwitch instance if the driver found an implementation for
- * the given description. Otherwise it returns OFSwitchImplBase
- */
- @Override
- public OpenFlowSwitchDriver getOFSwitchImpl(Dpid dpid,
- OFDescStatsReply desc, OFVersion ofv) {
- String vendor = desc.getMfrDesc();
- String hw = desc.getHwDesc();
- if (vendor.startsWith("Stanford University, Ericsson Research and CPqD Research")
- &&
- hw.startsWith("OpenFlow 1.3 Reference Userspace Switch")) {
- return new OFSwitchImplCPqD13(dpid, desc, cpqdUsePipeline13);
- }
-
- if (vendor.startsWith("Nicira") &&
- hw.startsWith("Open vSwitch")) {
- if (ofv == OFVersion.OF_10) {
- return new OFSwitchImplOVS10(dpid, desc);
- } else if (ofv == OFVersion.OF_13) {
- return new OFSwitchImplOVS13(dpid, desc);
- }
- }
-
- String sw = desc.getSwDesc();
- if (sw.startsWith("LINC-OE")) {
- log.warn("Optical Emulator LINC-OE with DPID:{} found..", dpid);
- return new OFOpticalSwitchImplLINC13(dpid, desc);
- }
-
- log.warn("DriverManager could not identify switch desc: {}. "
- + "Assigning AbstractOpenFlowSwich", desc);
- return new AbstractOpenFlowSwitch(dpid, desc) {
-
- @Override
- public void setRole(RoleState state) {
- this.role = RoleState.MASTER;
- }
-
- @Override
- public void write(List<OFMessage> msgs) {
- channel.write(msgs);
- }
-
- @Override
- public void write(OFMessage msg) {
- channel.write(Collections.singletonList(msg));
-
- }
-
- @Override
- public Boolean supportNxRole() {
- return false;
- }
-
- @Override
- public void startDriverHandshake() {}
-
- @Override
- public void processDriverHandshakeMessage(OFMessage m) {}
-
- @Override
- public boolean isDriverHandshakeComplete() {
- return true;
- }
-
- @Override
- public List<OFPortDesc> getPorts() {
- if (this.factory().getVersion() == OFVersion.OF_10) {
- return Collections.unmodifiableList(features.getPorts());
- } else {
- return Collections.unmodifiableList(ports.getEntries());
- }
- }
- };
- }
-
- /**
- * Private constructor to avoid instantiation.
- */
- private DriverManager() {
- }
-
- /**
- * Sets the configuration parameter which determines how the CPqD switch
- * is set up. If usePipeline13 is true, a 1.3 pipeline will be set up on
- * the switch. Otherwise, the switch will be set up in a 1.0 style with
- * a single table where missed packets are sent to the controller.
- *
- * @param usePipeline13 whether to use a 1.3 pipeline or not
- */
- public static void setConfigForCpqd(boolean usePipeline13) {
- cpqdUsePipeline13 = usePipeline13;
- }
-
- public static OpenFlowSwitchDriver getSwitch(Dpid dpid,
- OFDescStatsReply desc, OFVersion ofv) {
- return new DriverManager().getOFSwitchImpl(dpid, desc, ofv);
- }
-
-}
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java
deleted file mode 100644
index 66c017b..0000000
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright 2014 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.onlab.onos.openflow.drivers.impl;
-
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.onlab.onos.openflow.controller.Dpid;
-import org.onlab.onos.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFPortOptical;
-import org.projectfloodlight.openflow.protocol.OFStatsReply;
-import org.projectfloodlight.openflow.protocol.OFStatsType;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * LINC-OE Optical Emulator switch class.
- */
-public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
-
- private final AtomicBoolean driverHandshakeComplete;
- private long barrierXidToWaitFor = -1;
-
- private OFPortDescStatsReply wPorts;
-
- OFOpticalSwitchImplLINC13(Dpid dpid, OFDescStatsReply desc) {
- super(dpid);
- driverHandshakeComplete = new AtomicBoolean(false);
- setSwitchDescription(desc);
- }
-
- @Override
- public String toString() {
- return "OFOpticalSwitchImplLINC13 [" + ((channel != null)
- ? channel.getRemoteAddress() : "?")
- + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
- }
-
- @Override
- public void startDriverHandshake() {
- log.warn("Starting driver handshake for sw {}", getStringId());
- if (startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeAlreadyStarted();
- }
- startDriverHandshakeCalled = true;
- try {
- sendHandshakeOFExperimenterPortDescRequest();
- } catch (IOException e) {
- log.error("LINC-OE exception while sending experimenter port desc:",
- e.getMessage());
- e.printStackTrace();
- }
- }
-
- @Override
- public boolean isDriverHandshakeComplete() {
- if (!startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeNotStarted();
- }
- return driverHandshakeComplete.get();
- }
-
- @Override
- public void processDriverHandshakeMessage(OFMessage m) {
- if (!startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeNotStarted();
- }
- if (driverHandshakeComplete.get()) {
- throw new SwitchDriverSubHandshakeCompleted(m);
- }
-
- switch (m.getType()) {
- case BARRIER_REPLY:
- if (m.getXid() == barrierXidToWaitFor) {
- log.debug("LINC-OE Received barrier response");
- }
- break;
- case ERROR:
- log.error("Switch {} Error {}", getStringId(), m);
- break;
- case FEATURES_REPLY:
- break;
- case FLOW_REMOVED:
- break;
- case GET_ASYNC_REPLY:
- break;
- case PACKET_IN:
- break;
- case PORT_STATUS:
- log.warn("****LINC-OE Port Status {} {}", getStringId(), m);
- processOFPortStatus((OFCircuitPortStatus) m);
- break;
- case QUEUE_GET_CONFIG_REPLY:
- break;
- case ROLE_REPLY:
- break;
- case STATS_REPLY:
- OFStatsReply stats = (OFStatsReply) m;
- if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
- log.warn("LINC-OE : Received stats reply message {}", m);
- processHandshakeOFExperimenterPortDescRequest(
- (OFCircuitPortsReply) m);
- driverHandshakeComplete.set(true);
- }
- break;
- default:
- log.warn("Received message {} during switch-driver " +
- "subhandshake " + "from switch {} ... " +
- "Ignoring message", m,
- getStringId());
-
- }
- }
-
- //Todo
- public void processOFPortStatus(OFCircuitPortStatus ps) {
- log.debug("LINC-OE ..OF Port Status :", ps);
-
- }
-
- private void processHandshakeOFExperimenterPortDescRequest(
- OFCircuitPortsReply sr) {
- Collection<OFPortOptical> entries = sr.getEntries();
- List<OFPortDesc> ofPortDescList = new ArrayList<>(entries.size());
- for (OFPortOptical entry : entries) {
- log.warn("LINC:OE port message {}", entry.toString());
- ofPortDescList.add(factory().buildPortDesc().
- setPortNo(entry.getPortNo())
- .setConfig(entry.getConfig())
- .setState(entry.getState())
- .setHwAddr(entry.getHwAddr())
- .setName(entry.getName())
- .build());
-
- }
- setExperimenterPortDescReply(factory().buildPortDescStatsReply().
- setEntries(ofPortDescList).build());
- }
-
- private void setExperimenterPortDescReply(OFPortDescStatsReply reply) {
- wPorts = reply;
- }
-
-
- private void sendHandshakeOFExperimenterPortDescRequest() throws
- IOException {
- // send multi part message for port description for optical switches
- OFCircuitPortsRequest circuitPortsRequest = factory()
- .buildCircuitPortsRequest().setXid(getNextTransactionId())
- .build();
- log.warn("LINC-OE : Sending experimented circuit port stats " +
- "message " +
- "{}",
- circuitPortsRequest.toString());
- this.write(Collections.<OFMessage>singletonList(circuitPortsRequest));
- }
-
- @Override
- public List<OFPortDesc> getPorts() {
- List<OFPortDesc> portEntries = new ArrayList<>();
- portEntries.addAll(ports.getEntries());
- if (wPorts != null) {
- portEntries.addAll(wPorts.getEntries());
- }
- return Collections.unmodifiableList(portEntries);
- }
-
- @Override
- public void write(OFMessage msg) {
- this.channel.write(Collections.singletonList(msg));
- }
-
- @Override
- public void write(List<OFMessage> msgs) {
- this.channel.write(msgs);
- }
-
- @Override
- public Boolean supportNxRole() {
- return false;
- }
-
- @Override
- public boolean isOptical() {
- return true;
- }
-
-
-}
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplCPqD13.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplCPqD13.java
deleted file mode 100644
index 0905f43..0000000
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplCPqD13.java
+++ /dev/null
@@ -1,1234 +0,0 @@
-/*
- * Copyright 2014 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.onlab.onos.openflow.drivers.impl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.onlab.onos.openflow.controller.Dpid;
-import org.onlab.onos.openflow.controller.RoleState;
-import org.onlab.onos.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.projectfloodlight.openflow.protocol.OFAsyncGetReply;
-import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
-import org.projectfloodlight.openflow.protocol.OFBucket;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFGroupFeaturesStatsReply;
-import org.projectfloodlight.openflow.protocol.OFGroupType;
-import org.projectfloodlight.openflow.protocol.OFMatchV3;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFOxmList;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFStatsReply;
-import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmInPort;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmMetadataMasked;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
-import org.projectfloodlight.openflow.types.EthType;
-import org.projectfloodlight.openflow.types.IPv4Address;
-import org.projectfloodlight.openflow.types.MacAddress;
-import org.projectfloodlight.openflow.types.OFBufferId;
-import org.projectfloodlight.openflow.types.OFGroup;
-import org.projectfloodlight.openflow.types.OFMetadata;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.OFVlanVidMatch;
-import org.projectfloodlight.openflow.types.TableId;
-import org.projectfloodlight.openflow.types.U32;
-import org.projectfloodlight.openflow.types.U64;
-import org.projectfloodlight.openflow.util.HexString;
-
-/**
- * OFDescriptionStatistics Vendor (Manufacturer Desc.): Stanford University,
- * Ericsson Research and CPqD Research. Make (Hardware Desc.) : OpenFlow 1.3
- * Reference Userspace Switch Model (Datapath Desc.) : None Software : Serial :
- * None
- */
-public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
-
- private static final int VLAN_ID_OFFSET = 16;
- private final AtomicBoolean driverHandshakeComplete;
- private OFFactory factory;
- private static final int OFPCML_NO_BUFFER = 0xffff;
- // Configuration of asynch messages to controller. We need different
- // asynch messages depending on role-equal or role-master.
- // We don't want to get anything if we are slave.
- private static final long SET_FLOW_REMOVED_MASK_MASTER = 0xf;
- private static final long SET_PACKET_IN_MASK_MASTER = 0x7;
- private static final long SET_PORT_STATUS_MASK_MASTER = 0x7;
- private static final long SET_FLOW_REMOVED_MASK_EQUAL = 0x0;
- private static final long SET_PACKET_IN_MASK_EQUAL = 0x0;
- private static final long SET_PORT_STATUS_MASK_EQUAL = 0x7;
- private static final long SET_ALL_SLAVE = 0x0;
-
- private static final long TEST_FLOW_REMOVED_MASK = 0xf;
- private static final long TEST_PACKET_IN_MASK = 0x7;
- private static final long TEST_PORT_STATUS_MASK = 0x7;
- private long barrierXidToWaitFor = -1;
-
- private static final int TABLE_VLAN = 0;
- private static final int TABLE_TMAC = 1;
- private static final int TABLE_IPV4_UNICAST = 2;
- private static final int TABLE_MPLS = 3;
- private static final int TABLE_META = 4;
- private static final int TABLE_ACL = 5;
-
- private static final short MAX_PRIORITY = (short) 0xffff;
- private static final short SLASH_24_PRIORITY = (short) 0xfff0;
- private static final short MIN_PRIORITY = 0x0;
- private static final U64 METADATA_MASK = U64.of(Long.MAX_VALUE << 1 | 0x1);
-
- private final Map<Integer, OFGroup> l2groups;
-
- private final boolean usePipeline13;
-
- public OFSwitchImplCPqD13(Dpid dpid, OFDescStatsReply desc, boolean usePipeline13) {
- super(dpid);
- driverHandshakeComplete = new AtomicBoolean(false);
- l2groups = new ConcurrentHashMap<Integer, OFGroup>();
- setSwitchDescription(desc);
-
- this.usePipeline13 = usePipeline13;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "OFSwitchImplCPqD13 [" + ((channel != null)
- ? channel.getRemoteAddress() : "?")
- + " DPID[" + ((this.getStringId() != null) ? this.getStringId() : "?") + "]]";
- }
-
- @Override
- public void startDriverHandshake() {
- log.debug("Starting driver handshake for sw {}", getStringId());
- if (startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeAlreadyStarted();
- }
- startDriverHandshakeCalled = true;
- factory = this.factory();
- if (!usePipeline13) {
- // Send packet-in to controller if a packet misses the first table
- populateTableMissEntry(0, true, false, false, 0);
- } //else {
- // configureSwitch();
- //}
- sendBarrier(true);
- }
-
- @Override
- public boolean isDriverHandshakeComplete() {
- if (!startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeNotStarted();
- }
- return driverHandshakeComplete.get();
- }
-
- @Override
- public void processDriverHandshakeMessage(OFMessage m) {
- if (!startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeNotStarted();
- }
- if (driverHandshakeComplete.get()) {
- throw new SwitchDriverSubHandshakeCompleted(m);
- }
-
- switch (m.getType()) {
- case BARRIER_REPLY:
- if (m.getXid() == barrierXidToWaitFor) {
- driverHandshakeComplete.set(true);
- }
- break;
-
- case ERROR:
- log.error("Switch {} Error {}", getStringId(), m);
- break;
-
- case GET_ASYNC_REPLY:
- OFAsyncGetReply asrep = (OFAsyncGetReply) m;
- decodeAsyncGetReply(asrep);
- break;
- case STATS_REPLY:
- processStatsReply((OFStatsReply) m);
- break;
- case PACKET_IN:
- case PORT_STATUS:
- case QUEUE_GET_CONFIG_REPLY:
- case ROLE_REPLY:
- case FEATURES_REPLY:
- case FLOW_REMOVED:
- break;
-
- default:
- log.debug("Received message {} during switch-driver subhandshake "
- + "from switch {} ... Ignoring message", m, getStringId());
-
- }
- }
-
- private void configureSwitch() throws IOException {
- // setAsyncConfig();
- // getTableFeatures();
- sendGroupFeaturesRequest();
- setL2Groups();
- sendBarrier(false);
- setL3Groups();
- setL25Groups();
- sendGroupDescRequest();
- populateTableVlan();
- populateTableTMac();
- populateIpTable();
- populateMplsTable();
- populateTableMissEntry(TABLE_ACL, false, false, false, -1);
- sendBarrier(true);
- }
-
- private void setAsyncConfig() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>(3);
- OFMessage setAC = null;
-
- if (role == RoleState.MASTER) {
- setAC = factory.buildAsyncSet()
- .setFlowRemovedMaskEqualMaster(SET_FLOW_REMOVED_MASK_MASTER)
- .setPacketInMaskEqualMaster(SET_PACKET_IN_MASK_MASTER)
- .setPortStatusMaskEqualMaster(SET_PORT_STATUS_MASK_MASTER)
- .setFlowRemovedMaskSlave(SET_ALL_SLAVE)
- .setPacketInMaskSlave(SET_ALL_SLAVE)
- .setPortStatusMaskSlave(SET_ALL_SLAVE)
- .setXid(getNextTransactionId())
- .build();
- } else if (role == RoleState.EQUAL) {
- setAC = factory.buildAsyncSet()
- .setFlowRemovedMaskEqualMaster(SET_FLOW_REMOVED_MASK_EQUAL)
- .setPacketInMaskEqualMaster(SET_PACKET_IN_MASK_EQUAL)
- .setPortStatusMaskEqualMaster(SET_PORT_STATUS_MASK_EQUAL)
- .setFlowRemovedMaskSlave(SET_ALL_SLAVE)
- .setPacketInMaskSlave(SET_ALL_SLAVE)
- .setPortStatusMaskSlave(SET_ALL_SLAVE)
- .setXid(getNextTransactionId())
- .build();
- }
- msglist.add(setAC);
-
- OFMessage br = factory.buildBarrierRequest()
- .setXid(getNextTransactionId())
- .build();
- msglist.add(br);
-
- OFMessage getAC = factory.buildAsyncGetRequest()
- .setXid(getNextTransactionId())
- .build();
- msglist.add(getAC);
-
- sendMsg(msglist);
- }
-
- private void decodeAsyncGetReply(OFAsyncGetReply rep) {
- long frm = rep.getFlowRemovedMaskEqualMaster();
- //long frs = rep.getFlowRemovedMaskSlave();
- long pim = rep.getPacketInMaskEqualMaster();
- //long pis = rep.getPacketInMaskSlave();
- long psm = rep.getPortStatusMaskEqualMaster();
- //long pss = rep.getPortStatusMaskSlave();
-
- if (role == RoleState.MASTER || role == RoleState.EQUAL) { // should separate
- log.info("FRM:{}", HexString.toHexString((frm & TEST_FLOW_REMOVED_MASK)));
- log.info("PIM:{}", HexString.toHexString((pim & TEST_PACKET_IN_MASK)));
- log.info("PSM:{}", HexString.toHexString((psm & TEST_PORT_STATUS_MASK)));
- }
-
- }
-
- private void getTableFeatures() throws IOException {
- OFMessage gtf = factory.buildTableFeaturesStatsRequest()
- .setXid(getNextTransactionId())
- .build();
- sendMsg(gtf);
- }
-
- private void sendGroupFeaturesRequest() throws IOException {
- OFMessage gfr = factory.buildGroupFeaturesStatsRequest()
- .setXid(getNextTransactionId())
- .build();
- sendMsg(gfr);
- }
-
- private void sendGroupDescRequest() throws IOException {
- OFMessage gdr = factory.buildGroupDescStatsRequest()
- .setXid(getNextTransactionId())
- .build();
- sendMsg(gdr);
- }
-
- /*Create L2 interface groups for all physical ports
- Naming convention followed is the same as OF-DPA spec
- eg. port 1 with allowed vlan 10, is enveloped in group with id,
- 0x0 00a 0001, where the uppermost 4 bits identify an L2 interface,
- the next 12 bits identify the vlan-id, and the lowermost 16 bits
- identify the port number.*/
- private void setL2Groups() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- for (OFPortDesc p : getPorts()) {
- int pnum = p.getPortNo().getPortNumber();
- int portVlan = getVlanConfig(pnum);
- if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
- OFGroup gl2 = OFGroup.of(pnum | (portVlan << VLAN_ID_OFFSET));
- OFAction out = factory.actions().buildOutput()
- .setPort(p.getPortNo()).build();
- OFAction popVlan = factory.actions().popVlan();
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(popVlan);
- actions.add(out);
- OFBucket bucket = factory.buildBucket()
- .setActions(actions).build();
- List<OFBucket> buckets = Collections.singletonList(bucket);
- OFMessage gmAdd = factory.buildGroupAdd()
- .setGroup(gl2)
- .setBuckets(buckets)
- .setGroupType(OFGroupType.INDIRECT)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(gmAdd);
- l2groups.put(pnum, gl2);
- }
- }
- log.debug("Creating {} L2 groups in sw {}", msglist.size(), getStringId());
- sendMsg(msglist);
- }
-
- private int getVlanConfig(int portnum) {
- int portVlan = 10 * portnum;
- if ((getId() == 0x1 && portnum == 6) ||
- (getId() == 0x2) ||
- (getId() == 0x3 && portnum == 2)) {
- portVlan = 192; // 0xc0
- }
- return portVlan;
- }
-
- private MacAddress getRouterMacAddr() {
- if (getId() == 0x3) {
- return MacAddress.of("00:00:07:07:07:80"); // router mac
- }
- if (getId() == 0x1) {
- return MacAddress.of("00:00:01:01:01:80");
- }
- // switch 0x2
- return MacAddress.of("00:00:02:02:02:80");
- }
-
- // only for ports connected to other routers
- private OFAction getDestAction(int portnum) {
- OFAction setDA = null;
- MacAddress dAddr = null;
- if (getId() == 0x1 && portnum == 6) { // connected to switch 2
- dAddr = MacAddress.of("00:00:02:02:02:80");
- }
- if (getId() == 0x2) {
- if (portnum == 1) { // connected to sw 1
- dAddr = MacAddress.of("00:00:01:01:01:80");
- } else if (portnum == 2) { // connected to sw 3
- dAddr = MacAddress.of("00:00:07:07:07:80");
- }
- }
- if (getId() == 0x3) {
- if (portnum == 2) { // connected to switch 2
- dAddr = MacAddress.of("00:00:02:02:02:80");
- }
- }
-
- if (dAddr != null) {
- OFOxmEthDst dstAddr = factory.oxms().ethDst(dAddr);
- setDA = factory.actions().buildSetField()
- .setField(dstAddr).build();
- }
- return setDA;
- }
-
- /*
- * L3 groups are created for all router ports and they all point to corresponding
- * L2 groups. Only the ports that connect to other routers will have the
- * DA set.
- */
- private void setL3Groups() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- for (OFGroup gl2 : l2groups.values()) {
- int gnum = gl2.getGroupNumber();
- int portnum = gnum & 0x0000ffff;
- int vlanid = ((gnum & 0x0fff0000) >> VLAN_ID_OFFSET);
- MacAddress sAddr = getRouterMacAddr();
-
- OFGroup gl3 = OFGroup.of(0x20000000 | portnum);
- OFAction group = factory.actions().buildGroup()
- .setGroup(gl2).build();
- OFOxmEthSrc srcAddr = factory.oxms().ethSrc(sAddr);
- OFAction setSA = factory.actions().buildSetField()
- .setField(srcAddr).build();
- OFOxmVlanVid vid = factory.oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanid));
- OFAction setVlan = factory.actions().buildSetField()
- .setField(vid).build();
- OFAction decTtl = factory.actions().decNwTtl();
-
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(decTtl); // decrement the IP TTL/do-checksum/check TTL
- // and MTU
- actions.add(setVlan); // set the vlan-id of the exit-port (and
- // l2group)
- actions.add(setSA); // set this routers mac address
- // make L3Unicast group setDA for known (configured) ports
- // that connect to other routers
- OFAction setDA = getDestAction(portnum);
- if (setDA != null) {
- actions.add(setDA);
- }
- actions.add(group);
-
- OFBucket bucket = factory.buildBucket()
- .setActions(actions).build();
- List<OFBucket> buckets = Collections.singletonList(bucket);
- OFMessage gmAdd = factory.buildGroupAdd()
- .setGroup(gl3)
- .setBuckets(buckets)
- .setGroupType(OFGroupType.INDIRECT)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(gmAdd);
- }
- sendMsg(msglist);
- log.debug("Creating {} L3 groups in sw {}", msglist.size(), getStringId());
- }
-
- /*
- * L2.5 or mpls-unicast groups are only created for those router ports
- * connected to other router ports. They differ from the corresponding
- * L3-unicast group only by the fact that they decrement the MPLS TTL
- * instead of the IP ttl
- */
- private void setL25Groups() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- for (OFGroup gl2 : l2groups.values()) {
- int gnum = gl2.getGroupNumber();
- int portnum = gnum & 0x0000ffff;
- int vlanid = ((gnum & 0x0fff0000) >> VLAN_ID_OFFSET);
- MacAddress sAddr = getRouterMacAddr();
- OFAction setDA = getDestAction(portnum);
- // setDA will only be non-null for ports connected to routers
- if (setDA != null) {
- OFGroup gl3 = OFGroup.of(0xa0000000 | portnum); // different id
- // for mpls
- // group
- OFAction group = factory.actions().buildGroup()
- .setGroup(gl2).build();
- OFOxmEthSrc srcAddr = factory.oxms().ethSrc(sAddr);
- OFAction setSA = factory.actions().buildSetField()
- .setField(srcAddr).build();
- OFOxmVlanVid vid = factory.oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanid));
- OFAction setVlan = factory.actions().buildSetField()
- .setField(vid).build();
- OFAction decMplsTtl = factory.actions().decMplsTtl();
- List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(decMplsTtl); // decrement the MPLS
- // TTL/do-checksum/check TTL and MTU
- actions.add(setVlan); // set the vlan-id of the exit-port (and
- // l2group)
- actions.add(setSA); // set this routers mac address
- actions.add(setDA);
- actions.add(group);
- OFBucket bucket = factory.buildBucket()
- .setActions(actions).build();
- List<OFBucket> buckets = Collections.singletonList(bucket);
- OFMessage gmAdd = factory.buildGroupAdd()
- .setGroup(gl3)
- .setBuckets(buckets)
- .setGroupType(OFGroupType.INDIRECT)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(gmAdd);
- }
- }
- sendMsg(msglist);
- log.debug("Creating {} MPLS groups in sw {}", msglist.size(), getStringId());
- }
-
- /* Using ECMP groups
- *
- * OFGroup group47 = OFGroup.of(47);
- OFAction outgroup1 = factory.actions()
- .buildGroup()
- .setGroup(group61)
- .build();
- OFBucket buc47_1 = factory.buildBucket()
- .setWeight(1)
- .setActions(Collections.singletonList(outgroup1))
- .build();
- OFAction outgroup2 = factory.actions()
- .buildGroup()
- .setGroup(group62)
- .build();
- OFBucket buc47_2 = factory.buildBucket()
- .setWeight(1)
- .setActions(Collections.singletonList(outgroup2))
- .build();
- List<OFBucket> buckets47 = new ArrayList<OFBucket>();
- buckets47.add(buc47_1);
- buckets47.add(buc47_2);
- OFMessage gmS12 = factory.buildGroupAdd()
- .setGroup(group47)
- .setBuckets(buckets47)
- .setGroupType(OFGroupType.SELECT)
- .setXid(getNextTransactionId())
- .build();
- write(gmS12, null); */
-
- private void processStatsReply(OFStatsReply sr) {
- switch (sr.getStatsType()) {
- case AGGREGATE:
- break;
- case DESC:
- break;
- case EXPERIMENTER:
- break;
- case FLOW:
- break;
- case GROUP_DESC:
- processGroupDesc((OFGroupDescStatsReply) sr);
- break;
- case GROUP_FEATURES:
- processGroupFeatures((OFGroupFeaturesStatsReply) sr);
- break;
- case METER_CONFIG:
- break;
- case METER_FEATURES:
- break;
- case PORT_DESC:
- break;
- case TABLE_FEATURES:
- break;
- default:
- break;
-
- }
- }
-
- private void processGroupFeatures(OFGroupFeaturesStatsReply gfsr) {
- log.info("Sw: {} Group Features {}", getStringId(), gfsr);
- }
-
- private void processGroupDesc(OFGroupDescStatsReply gdsr) {
- log.info("Sw: {} Group Desc {}", getStringId(), gdsr);
- }
-
- private void populateTableVlan() throws IOException {
- // for all incoming ports assign configured port-vlans
- // currently assign portnum*10 -> vlanid to access ports
- // and vlan 192 to router to router ports
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- for (OFPortDesc p : getPorts()) {
- int pnum = p.getPortNo().getPortNumber();
- if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
- int vlanid = getVlanConfig(pnum);
- OFOxmInPort oxp = factory.oxms().inPort(p.getPortNo());
- OFOxmVlanVid oxv = factory.oxms()
- .vlanVid(OFVlanVidMatch.UNTAGGED);
- OFOxmList oxmList = OFOxmList.of(oxp, oxv);
- OFMatchV3 match = factory.buildMatchV3()
- .setOxmList(oxmList).build();
- OFOxmVlanVid vidToSet = factory.oxms()
- .vlanVid(OFVlanVidMatch.ofVlan(vlanid));
- OFAction pushVlan = factory.actions().pushVlan(EthType.VLAN_FRAME);
- OFAction setVlan = factory.actions().setField(vidToSet);
- List<OFAction> actionlist = new ArrayList<OFAction>();
- actionlist.add(pushVlan);
- actionlist.add(setVlan);
- OFInstruction appAction = factory.instructions().buildApplyActions()
- .setActions(actionlist).build();
- OFInstruction gotoTbl = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_TMAC)).build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(appAction);
- instructions.add(gotoTbl);
- OFMessage flowEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_VLAN))
- .setMatch(match)
- .setInstructions(instructions)
- .setPriority(1000) // does not matter - all rules
- // exclusive
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(flowEntry);
- }
- }
- // table-vlan has no table-miss entry, and so packets that miss are
- // essentially dropped
- sendMsg(msglist);
- log.debug("Adding {} vlan-rules in sw {}", msglist.size(), getStringId());
- }
-
- private void populateTableTMac() throws IOException {
- // match for ip packets
- OFOxmEthType oxe = factory.oxms().ethType(EthType.IPv4);
- OFOxmList oxmListIp = OFOxmList.of(oxe);
- OFMatchV3 matchIp = factory.buildMatchV3()
- .setOxmList(oxmListIp).build();
- OFInstruction gotoTblIp = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST)).build();
- List<OFInstruction> instructionsIp = Collections.singletonList(gotoTblIp);
- OFMessage ipEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_TMAC))
- .setMatch(matchIp)
- .setInstructions(instructionsIp)
- .setPriority(1000) // strict priority required lower than
- // multicastMac
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
-
- // match for mpls packets
- OFOxmEthType oxmpls = factory.oxms().ethType(EthType.MPLS_UNICAST);
- OFOxmList oxmListMpls = OFOxmList.of(oxmpls);
- OFMatchV3 matchMpls = factory.buildMatchV3()
- .setOxmList(oxmListMpls).build();
- OFInstruction gotoTblMpls = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_MPLS)).build();
- List<OFInstruction> instructionsMpls = Collections.singletonList(gotoTblMpls);
- OFMessage mplsEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_TMAC))
- .setMatch(matchMpls)
- .setInstructions(instructionsMpls)
- .setPriority(1001) // strict priority required lower than
- // multicastMac
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
-
- // match for everything else to send to controller. Essentially
- // the table miss flow entry
- populateTableMissEntry(TABLE_TMAC, true, false, false, -1);
- log.debug("Adding termination-mac-rules in sw {}", getStringId());
- List<OFMessage> msglist = new ArrayList<OFMessage>(2);
- msglist.add(ipEntry);
- msglist.add(mplsEntry);
- sendMsg(msglist);
- }
-
- private List<String> getMyIps() { // send to controller
- List<String> myIps = new ArrayList<String>();
- if (getId() == 0x1) {
- myIps.add("10.0.2.128");
- myIps.add("10.0.3.128");
- myIps.add("10.0.1.128");
- myIps.add("192.168.0.1");
- }
- if (getId() == 0x2) {
- myIps.add("192.168.0.2");
- }
- if (getId() == 0x3) {
- myIps.add("192.168.0.3");
- myIps.add("7.7.7.128");
- }
- return myIps;
- }
-
- private List<String> getMySubnetIps() { // send to controller
- List<String> subnetIps = new ArrayList<String>();
- if (getId() == 0x1) {
- subnetIps.add("10.0.2.0");
- subnetIps.add("10.0.3.0");
- subnetIps.add("10.0.1.0");
- }
- // TODO needed?
- //if (getId() == 0x2) {
- //}
- if (getId() == 0x3) {
- subnetIps.add("7.7.7.0");
- }
- return subnetIps;
- }
-
- private static class RouteEntry {
- String prefix;
- String mask;
- int nextHopPort;
- String dstMac;
- int label;
-
- public RouteEntry(String prefix, String mask, int nextHopPort, int label) {
- this.prefix = prefix;
- this.mask = mask;
- this.nextHopPort = nextHopPort;
- this.label = label;
- }
-
- public RouteEntry(String prefix, int nextHopPort, String dstMac) {
- this.prefix = prefix;
- this.nextHopPort = nextHopPort;
- this.dstMac = dstMac;
- }
- }
-
- // send out of mpls-group where the next-hop mac-da is already set
- private List<RouteEntry> getRouterNextHopIps() {
- List<RouteEntry> routerNextHopIps = new ArrayList<RouteEntry>();
- if (getId() == 0x1) {
- routerNextHopIps
- .add(new RouteEntry("192.168.0.2", "255.255.255.255", 6, 102));
- routerNextHopIps
- .add(new RouteEntry("192.168.0.3", "255.255.255.255", 6, 103));
- routerNextHopIps.add(new RouteEntry("7.7.7.0", "255.255.255.0", 6, 103));
- }
- //if (getId() == 0x2) {
- /* These are required for normal IP routing without labels.
- routerNextHopIps.add(new RouteEntry("192.168.0.1","255.255.255.255",1));
- routerNextHopIps.add(new RouteEntry("192.168.0.3","255.255.255.255",2));
- routerNextHopIps.add(new RouteEntry("10.0.1.0","255.255.255.0",1));
- routerNextHopIps.add(new RouteEntry("10.0.2.0","255.255.255.0",1));
- routerNextHopIps.add(new RouteEntry("10.0.3.0","255.255.255.0",1));
- routerNextHopIps.add(new RouteEntry("7.7.7.0","255.255.255.0",2));*/
- //}
- if (getId() == 0x3) {
- routerNextHopIps
- .add(new RouteEntry("192.168.0.2", "255.255.255.255", 2, 102));
- routerNextHopIps
- .add(new RouteEntry("192.168.0.1", "255.255.255.255", 2, 101));
- routerNextHopIps.add(new RouteEntry("10.0.1.0", "255.255.255.0", 2, 101));
- routerNextHopIps.add(new RouteEntry("10.0.2.0", "255.255.255.0", 2, 101));
- routerNextHopIps.add(new RouteEntry("10.0.3.0", "255.255.255.0", 2, 101));
- }
- return routerNextHopIps;
- }
-
- // known host mac-addr, setDA/send out of l3group
- private List<RouteEntry> getHostNextHopIps() {
- List<RouteEntry> hostNextHopIps = new ArrayList<RouteEntry>();
- if (getId() == 0x1) {
- hostNextHopIps.add(new RouteEntry("10.0.2.1", 4, "00:00:00:00:02:01"));
- hostNextHopIps.add(new RouteEntry("10.0.3.1", 5, "00:00:00:00:03:01"));
- }
- // TODO needed?
- //if (getId() == 0x2) {
- //}
- if (getId() == 0x3) {
- hostNextHopIps.add(new RouteEntry("7.7.7.7", 1, "00:00:07:07:07:07"));
- }
- return hostNextHopIps;
- }
-
- private void populateIpTable() throws IOException {
- populateMyIps();
- populateMySubnets();
- populateRoutes();
- populateHostRoutes();
-
- // match for everything else to send to ACL table. Essentially
- // the table miss flow entry
- populateTableMissEntry(TABLE_IPV4_UNICAST, false, true,
- true, TABLE_ACL);
- }
-
- private void populateMyIps() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- // first all my ip's as exact-matches
- // write-action instruction to send to controller
- List<String> myIps = getMyIps();
- for (int i = 0; i < myIps.size(); i++) {
- OFOxmEthType ethTypeIp = factory.oxms()
- .ethType(EthType.IPv4);
- OFOxmIpv4DstMasked ipPrefix = factory.oxms()
- .ipv4DstMasked(IPv4Address.of(myIps.get(i)), IPv4Address.NO_MASK);
- OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
- OFMatchV3 match = factory.buildMatchV3()
- .setOxmList(oxmListSlash32).build();
- OFAction outc = factory.actions().buildOutput()
- .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
- .build();
- OFInstruction writeInstr = factory.instructions().buildWriteActions()
- .setActions(Collections.singletonList(outc)).build();
- OFInstruction gotoInstr = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_ACL)).build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(writeInstr);
- instructions.add(gotoInstr);
- OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST))
- .setMatch(match)
- .setInstructions(instructions)
- .setPriority(MAX_PRIORITY) // highest priority for exact
- // match
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(myIpEntry);
- }
- sendMsg(msglist);
- log.debug("Adding {} my-ip-rules in sw {}", msglist.size(), getStringId());
- }
-
- private void populateMySubnets() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- // next prefix-based subnet-IP's configured on my interfaces
- // need to ARP for exact-IP, so write-action instruction to send to
- // controller
- // this has different mask and priority than earlier case
- List<String> subnetIps = getMySubnetIps();
- for (int i = 0; i < subnetIps.size(); i++) {
- OFOxmEthType ethTypeIp = factory.oxms()
- .ethType(EthType.IPv4);
- OFOxmIpv4DstMasked ipPrefix = factory.oxms().ipv4DstMasked(
- IPv4Address.of(subnetIps.get(i)),
- IPv4Address.of(0xffffff00)); // '/24' mask
- OFOxmList oxmListSlash24 = OFOxmList.of(ethTypeIp, ipPrefix);
- OFMatchV3 match = factory.buildMatchV3()
- .setOxmList(oxmListSlash24).build();
- OFAction outc = factory.actions().buildOutput()
- .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
- .build();
- OFInstruction writeInstr = factory.instructions().buildWriteActions()
- .setActions(Collections.singletonList(outc)).build();
- OFInstruction gotoInstr = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_ACL)).build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(writeInstr);
- instructions.add(gotoInstr);
- OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST))
- .setMatch(match)
- .setInstructions(instructions)
- .setPriority(SLASH_24_PRIORITY)
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(myIpEntry);
- }
- sendMsg(msglist);
- log.debug("Adding {} subnet-ip-rules in sw {}", msglist.size(), getStringId());
- msglist.clear();
- }
-
- private void populateRoutes() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- // addresses where I know the next-hop's mac-address because it is a
- // router port - so I have an L3 interface to it (and an MPLS interface)
- List<RouteEntry> routerNextHopIps = getRouterNextHopIps();
- for (int i = 0; i < routerNextHopIps.size(); i++) {
- OFOxmEthType ethTypeIp = factory.oxms()
- .ethType(EthType.IPv4);
- OFOxmIpv4DstMasked ipPrefix = factory.oxms()
- .ipv4DstMasked(
- IPv4Address.of(routerNextHopIps.get(i).prefix),
- IPv4Address.of(routerNextHopIps.get(i).mask)
- );
- OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
- OFMatchV3 match = factory.buildMatchV3()
- .setOxmList(oxmListSlash32).build();
- OFAction outg = factory.actions().buildGroup()
- .setGroup(OFGroup.of(0xa0000000 | // mpls group id
- routerNextHopIps.get(i).nextHopPort))
- .build();
- // lots of actions before forwarding to mpls group, and
- // unfortunately
- // they need to be apply-actions
-
- OFAction pushlabel = factory.actions().pushMpls(EthType.MPLS_UNICAST);
- OFOxmMplsLabel l = factory.oxms()
- .mplsLabel(U32.of(routerNextHopIps.get(i).label));
- OFAction setlabelid = factory.actions().buildSetField()
- .setField(l).build();
- OFAction copyTtlOut = factory.actions().copyTtlOut();
- // OFAction setBos =
- // factory.actions().buildSetField().setField(bos).build();
-
- /*
- writeActions.add(pushlabel); // need to be apply actions so can be
- writeActions.add(copyTtlOut); // matched in pseudo-table
- //writeActions.add(setlabelid); // bad support in cpqd
- //writeActions.add(setBos); no support in loxigen
- */
-
- List<OFAction> applyActions = new ArrayList<OFAction>();
- applyActions.add(pushlabel);
- applyActions.add(copyTtlOut);
- OFInstruction applyInstr = factory.instructions().buildApplyActions()
- .setActions(applyActions).build();
- List<OFAction> writeActions = new ArrayList<OFAction>();
- writeActions.add(outg); // group will decr mpls-ttl, set mac-sa/da,
- // vlan
- OFInstruction writeInstr = factory.instructions().buildWriteActions()
- .setActions(writeActions).build();
-
- // necessary to match in pseudo-table to overcome cpqd 1.3 flaw
- OFInstruction writeMeta = factory.instructions().buildWriteMetadata()
- .setMetadata(U64.of(routerNextHopIps.get(i).label))
- .setMetadataMask(METADATA_MASK).build();
- /*OFInstruction gotoInstr = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_ACL)).build();*/
- OFInstruction gotoInstr = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_META)).build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(applyInstr);
- // instructions.add(writeInstr);// cannot write here - causes switch
- // to crash
- instructions.add(writeMeta);
- instructions.add(gotoInstr);
-
- int priority = -1;
- if (routerNextHopIps.get(i).mask.equals("255.255.255.255")) {
- priority = MAX_PRIORITY;
- } else {
- priority = SLASH_24_PRIORITY;
- }
- OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST))
- .setMatch(match)
- .setInstructions(instructions)
- .setPriority(priority)
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(myIpEntry);
-
- // need to also handle psuedo-table entries to match-metadata and
- // set mpls
- // label-id
- OFOxmEthType ethTypeMpls = factory.oxms()
- .ethType(EthType.MPLS_UNICAST);
- OFOxmMetadataMasked meta = factory.oxms()
- .metadataMasked(
- OFMetadata.ofRaw(routerNextHopIps.get(i).label),
- OFMetadata.NO_MASK);
- OFOxmList oxmListMeta = OFOxmList.of(ethTypeMpls, meta);
- OFMatchV3 matchMeta = factory.buildMatchV3()
- .setOxmList(oxmListMeta).build();
- List<OFAction> writeActions2 = new ArrayList<OFAction>();
- writeActions2.add(setlabelid);
- OFAction outg2 = factory.actions().buildGroup()
- .setGroup(OFGroup.of(routerNextHopIps.get(i).nextHopPort |
- (192 << VLAN_ID_OFFSET)))
- .build();
- writeActions2.add(outg2);
- OFInstruction writeInstr2 = factory.instructions().buildWriteActions()
- .setActions(writeActions2).build();
- OFInstruction gotoInstr2 = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_ACL)).build();
- List<OFInstruction> instructions2 = new ArrayList<OFInstruction>();
- // unfortunately have to apply this action too
- OFInstruction applyInstr2 = factory.instructions().buildApplyActions()
- .setActions(writeActions2).build();
- instructions2.add(applyInstr2);
- // instructions2.add(writeInstr2);
- // instructions2.add(gotoInstr2);
-
- /*OFMatchV3 match3 = factory.buildMatchV3()
- .setOxmList(OFOxmList.of(meta)).build();
- OFInstruction clearInstruction = factory.instructions().clearActions();
- List<OFInstruction> instructions3 = new ArrayList<OFInstruction>();
- OFAction outc = factory.actions().buildOutput()
- .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
- .build();
- OFInstruction writec = factory.instructions()
- .writeActions(Collections.singletonList(outc));
- instructions3.add(clearInstruction);
- instructions3.add(writec);
- instructions3.add(gotoInstr2); */
- OFMessage myMetaEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_META))
- .setMatch(matchMeta)
- .setInstructions(instructions2)
- .setPriority(MAX_PRIORITY)
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(myMetaEntry);
-
- }
- sendMsg(msglist);
- log.debug("Adding {} next-hop-router-rules in sw {}", msglist.size(),
- getStringId());
-
- // add a table-miss entry to table 4 for debugging - leave it out
- // unclear packet state - causes switch to crash
- // populateTableMissEntry(TABLE_META, false, true,
- // true, TABLE_ACL);
- }
-
- private void populateHostRoutes() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- // addresses where I know the next hop's mac-address and I can set the
- // destination mac in the match-instruction.write-action
- // either I sent out arp-request or I got an arp-request from this host
- List<RouteEntry> hostNextHopIps = getHostNextHopIps();
- for (int i = 0; i < hostNextHopIps.size(); i++) {
- OFOxmEthType ethTypeIp = factory.oxms()
- .ethType(EthType.IPv4);
- OFOxmIpv4DstMasked ipPrefix = factory.oxms()
- .ipv4DstMasked(
- IPv4Address.of(hostNextHopIps.get(i).prefix),
- IPv4Address.NO_MASK); // host addr should be /32
- OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
- OFMatchV3 match = factory.buildMatchV3()
- .setOxmList(oxmListSlash32).build();
- OFAction setDmac = null, outg = null;
- OFOxmEthDst dmac = factory.oxms()
- .ethDst(MacAddress.of(hostNextHopIps.get(i).dstMac));
- setDmac = factory.actions().buildSetField()
- .setField(dmac).build();
- outg = factory.actions().buildGroup()
- .setGroup(OFGroup.of(0x20000000 | hostNextHopIps.get(i).nextHopPort)) // l3group
- // id
- .build();
- List<OFAction> writeActions = new ArrayList<OFAction>();
- writeActions.add(setDmac);
- writeActions.add(outg);
- OFInstruction writeInstr = factory.instructions().buildWriteActions()
- .setActions(writeActions).build();
- OFInstruction gotoInstr = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_ACL)).build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(writeInstr);
- instructions.add(gotoInstr);
- OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST))
- .setMatch(match)
- .setInstructions(instructions)
- .setPriority(MAX_PRIORITY) // highest priority for exact
- // match
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(myIpEntry);
- }
- sendMsg(msglist);
- log.debug("Adding {} next-hop-host-rules in sw {}", msglist.size(), getStringId());
- }
-
- private static class MplsEntry {
- int labelid;
- int portnum;
-
- public MplsEntry(int labelid, int portnum) {
- this.labelid = labelid;
- this.portnum = portnum;
- }
- }
-
- private List<MplsEntry> getMplsEntries() {
- List<MplsEntry> myLabels = new ArrayList<MplsEntry>();
- if (getId() == 0x1) {
- myLabels.add(new MplsEntry(101, OFPort.CONTROLLER.getPortNumber()));
- myLabels.add(new MplsEntry(103, 6));
- }
- if (getId() == 0x2) {
- myLabels.add(new MplsEntry(103, 2));
- myLabels.add(new MplsEntry(102, OFPort.CONTROLLER.getPortNumber()));
- myLabels.add(new MplsEntry(101, 1));
- }
- if (getId() == 0x3) {
- myLabels.add(new MplsEntry(103, OFPort.CONTROLLER.getPortNumber()));
- myLabels.add(new MplsEntry(101, 2));
- }
- return myLabels;
- }
-
- private void populateMplsTable() throws IOException {
- List<OFMessage> msglist = new ArrayList<OFMessage>();
- List<MplsEntry> lfibEntries = getMplsEntries();
- for (int i = 0; i < lfibEntries.size(); i++) {
- OFOxmEthType ethTypeMpls = factory.oxms()
- .ethType(EthType.MPLS_UNICAST);
- OFOxmMplsLabel labelid = factory.oxms()
- .mplsLabel(U32.of(lfibEntries.get(i).labelid));
- OFOxmList oxmList = OFOxmList.of(ethTypeMpls, labelid);
- OFMatchV3 matchlabel = factory.buildMatchV3()
- .setOxmList(oxmList).build();
- OFAction poplabel = factory.actions().popMpls(EthType.IPv4);
- OFAction sendTo = null;
- if (lfibEntries.get(i).portnum == OFPort.CONTROLLER.getPortNumber()) {
- sendTo = factory.actions().output(OFPort.CONTROLLER,
- OFPCML_NO_BUFFER);
- } else {
- sendTo = factory.actions().group(OFGroup.of(
- 0xa0000000 | lfibEntries.get(i).portnum));
- }
- List<OFAction> writeActions = new ArrayList<OFAction>();
- writeActions.add(poplabel);
- writeActions.add(sendTo);
- OFInstruction writeInstr = factory.instructions().buildWriteActions()
- .setActions(writeActions).build();
- OFInstruction gotoInstr = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_ACL)).build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(writeInstr);
- instructions.add(gotoInstr);
- OFMessage myMplsEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_MPLS))
- .setMatch(matchlabel)
- .setInstructions(instructions)
- .setPriority(MAX_PRIORITY) // exact match and exclusive
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- msglist.add(myMplsEntry);
- }
- sendMsg(msglist);
- log.debug("Adding {} mpls-forwarding-rules in sw {}", msglist.size(),
- getStringId());
-
- // match for everything else to send to ACL table. Essentially
- // the table miss flow entry
- populateTableMissEntry(TABLE_MPLS, false, true,
- true, TABLE_ACL);
-
- }
-
- /**
- * By default if none of the booleans in the call are set, then the
- * table-miss entry is added with no instructions, which means that pipeline
- * execution will stop, and the action set associated with the packet will
- * be executed.
- *
- * @param tableToAdd
- * @param toControllerNow as an APPLY_ACTION instruction
- * @param toControllerWrite as a WRITE_ACITION instruction
- * @param toTable as a GOTO_TABLE instruction
- * @param tableToSend
- * @throws IOException
- */
- @SuppressWarnings("unchecked")
- private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
- boolean toControllerWrite,
- boolean toTable, int tableToSend) {
- OFOxmList oxmList = OFOxmList.EMPTY;
- OFMatchV3 match = factory.buildMatchV3()
- .setOxmList(oxmList)
- .build();
- OFAction outc = factory.actions()
- .buildOutput()
- .setPort(OFPort.CONTROLLER)
- .setMaxLen(OFPCML_NO_BUFFER)
- .build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- if (toControllerNow) {
- // table-miss instruction to send to controller immediately
- OFInstruction instr = factory.instructions()
- .buildApplyActions()
- .setActions(Collections.singletonList(outc))
- .build();
- instructions.add(instr);
- }
-
- if (toControllerWrite) {
- // table-miss instruction to write-action to send to controller
- // this will be executed whenever the action-set gets executed
- OFInstruction instr = factory.instructions()
- .buildWriteActions()
- .setActions(Collections.singletonList(outc))
- .build();
- instructions.add(instr);
- }
-
- if (toTable) {
- // table-miss instruction to goto-table x
- OFInstruction instr = factory.instructions()
- .gotoTable(TableId.of(tableToSend));
- instructions.add(instr);
- }
-
- if (!toControllerNow && !toControllerWrite && !toTable) {
- // table-miss has no instruction - at which point action-set will be
- // executed - if there is an action to output/group in the action
- // set
- // the packet will be sent there, otherwise it will be dropped.
- instructions = Collections.EMPTY_LIST;
- }
-
- OFMessage tableMissEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(tableToAdd))
- .setMatch(match) // match everything
- .setInstructions(instructions)
- .setPriority(MIN_PRIORITY)
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
-
- write(tableMissEntry);
- }
-
- private void sendBarrier(boolean finalBarrier) {
- int xid = getNextTransactionId();
- if (finalBarrier) {
- barrierXidToWaitFor = xid;
- }
- OFBarrierRequest br = factory
- .buildBarrierRequest()
- .setXid(xid)
- .build();
-
- write(br);
- }
-
- @Override
- public Boolean supportNxRole() {
- return false;
- }
-
- @Override
- public void write(OFMessage msg) {
- this.channel.write(Collections.singletonList(msg));
-
- }
-
- @Override
- public void write(List<OFMessage> msgs) {
- this.channel.write(msgs);
- }
-
-}
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplOVS10.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplOVS10.java
deleted file mode 100644
index a1ae8a9..0000000
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplOVS10.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2014 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.onlab.onos.openflow.drivers.impl;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.onlab.onos.openflow.controller.Dpid;
-import org.onlab.onos.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-
-/**
- * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
- * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
- * 1.11.90 (or whatever version + build) Serial : None
- */
-public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
-
- public OFSwitchImplOVS10(Dpid dpid, OFDescStatsReply desc) {
- super(dpid);
- setSwitchDescription(desc);
-
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "OFSwitchImplOVS10 [" + ((channel != null)
- ? channel.getRemoteAddress() : "?")
- + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
- }
-
- @Override
- public Boolean supportNxRole() {
- return true;
- }
-
- @Override
- public void startDriverHandshake() {}
-
- @Override
- public boolean isDriverHandshakeComplete() {
- return true;
- }
-
- @Override
- public void processDriverHandshakeMessage(OFMessage m) {}
-
- @Override
- public void write(OFMessage msg) {
- channel.write(Collections.singletonList(msg));
- }
-
- @Override
- public void write(List<OFMessage> msgs) {
- channel.write(msgs);
- }
-
- @Override
- public List<OFPortDesc> getPorts() {
- return Collections.unmodifiableList(features.getPorts());
- }
-
-
-}
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplOVS13.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplOVS13.java
deleted file mode 100644
index c32d889..0000000
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplOVS13.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2014 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.onlab.onos.openflow.drivers.impl;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.onlab.onos.openflow.controller.Dpid;
-import org.onlab.onos.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFMatchV3;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFOxmList;
-import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.types.OFBufferId;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.TableId;
-
-/**
- * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
- * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
- * 2.1.0 (or whatever version + build) Serial : None
- */
-public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
-
- private final AtomicBoolean driverHandshakeComplete;
- private OFFactory factory;
- private long barrierXidToWaitFor = -1;
-
- private static final short MIN_PRIORITY = 0x0;
- private static final int OFPCML_NO_BUFFER = 0xffff;
-
- public OFSwitchImplOVS13(Dpid dpid, OFDescStatsReply desc) {
- super(dpid);
- driverHandshakeComplete = new AtomicBoolean(false);
- setSwitchDescription(desc);
- }
-
- @Override
- public String toString() {
- return "OFSwitchImplOVS13 [" + ((channel != null)
- ? channel.getRemoteAddress() : "?")
- + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
- }
-
- @Override
- public void startDriverHandshake() {
- log.debug("Starting driver handshake for sw {}", getStringId());
- if (startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeAlreadyStarted();
- }
- startDriverHandshakeCalled = true;
- factory = factory();
- configureSwitch();
- }
-
- @Override
- public boolean isDriverHandshakeComplete() {
- if (!startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeNotStarted();
- }
- return driverHandshakeComplete.get();
- }
-
- @Override
- public void processDriverHandshakeMessage(OFMessage m) {
- if (!startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeNotStarted();
- }
- if (driverHandshakeComplete.get()) {
- throw new SwitchDriverSubHandshakeCompleted(m);
- }
-
- switch (m.getType()) {
- case BARRIER_REPLY:
- if (m.getXid() == barrierXidToWaitFor) {
- driverHandshakeComplete.set(true);
- }
- break;
-
- case ERROR:
- log.error("Switch {} Error {}", getStringId(), m);
- break;
-
- case FEATURES_REPLY:
- break;
- case FLOW_REMOVED:
- break;
- case GET_ASYNC_REPLY:
- // OFAsyncGetReply asrep = (OFAsyncGetReply)m;
- // decodeAsyncGetReply(asrep);
- break;
-
- case PACKET_IN:
- break;
- case PORT_STATUS:
- break;
- case QUEUE_GET_CONFIG_REPLY:
- break;
- case ROLE_REPLY:
- break;
-
- case STATS_REPLY:
- // processStatsReply((OFStatsReply) m);
- break;
-
- default:
- log.debug("Received message {} during switch-driver subhandshake "
- + "from switch {} ... Ignoring message", m, getStringId());
-
- }
- }
-
-
- private void configureSwitch() {
- populateTableMissEntry(0, true, false, false, 0);
- sendBarrier(true);
- }
-
-
- private void sendBarrier(boolean finalBarrier) {
- int xid = getNextTransactionId();
- if (finalBarrier) {
- barrierXidToWaitFor = xid;
- }
- OFBarrierRequest br = factory
- .buildBarrierRequest()
- .setXid(xid)
- .build();
- write(br);
- }
-
- @Override
- public Boolean supportNxRole() {
- return false;
- }
-
- @Override
- public void write(OFMessage msg) {
- channel.write(Collections.singletonList(msg));
-
- }
-
- @Override
- public void write(List<OFMessage> msgs) {
- channel.write(msgs);
- }
-
- /**
- * By default if none of the booleans in the call are set, then the
- * table-miss entry is added with no instructions, which means that pipeline
- * execution will stop, and the action set associated with the packet will
- * be executed.
- *
- * @param tableToAdd
- * @param toControllerNow as an APPLY_ACTION instruction
- * @param toControllerWrite as a WRITE_ACITION instruction
- * @param toTable as a GOTO_TABLE instruction
- * @param tableToSend
- */
- @SuppressWarnings("unchecked")
- private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
- boolean toControllerWrite,
- boolean toTable, int tableToSend) {
- OFOxmList oxmList = OFOxmList.EMPTY;
- OFMatchV3 match = factory.buildMatchV3()
- .setOxmList(oxmList)
- .build();
- OFAction outc = factory.actions()
- .buildOutput()
- .setPort(OFPort.CONTROLLER)
- .setMaxLen(OFPCML_NO_BUFFER)
- .build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- if (toControllerNow) {
- // table-miss instruction to send to controller immediately
- OFInstruction instr = factory.instructions()
- .buildApplyActions()
- .setActions(Collections.singletonList(outc))
- .build();
- instructions.add(instr);
- }
-
- if (toControllerWrite) {
- // table-miss instruction to write-action to send to controller
- // this will be executed whenever the action-set gets executed
- OFInstruction instr = factory.instructions()
- .buildWriteActions()
- .setActions(Collections.singletonList(outc))
- .build();
- instructions.add(instr);
- }
-
- if (toTable) {
- // table-miss instruction to goto-table x
- OFInstruction instr = factory.instructions()
- .gotoTable(TableId.of(tableToSend));
- instructions.add(instr);
- }
-
- if (!toControllerNow && !toControllerWrite && !toTable) {
- // table-miss has no instruction - at which point action-set will be
- // executed - if there is an action to output/group in the action
- // set
- // the packet will be sent there, otherwise it will be dropped.
- instructions = Collections.EMPTY_LIST;
- }
-
- OFMessage tableMissEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(tableToAdd))
- .setMatch(match) // match everything
- .setInstructions(instructions)
- .setPriority(MIN_PRIORITY)
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- write(tableMissEntry);
- }
-
-}
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/package-info.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/package-info.java
deleted file mode 100644
index a8581b4..0000000
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-/**
- * OpenFlow base switch drivers implementations.
- */
-package org.onlab.onos.openflow.drivers.impl;