refactored OF switch into driver and frontend
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/AbstractOpenFlowSwitch.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/AbstractOpenFlowSwitch.java
deleted file mode 100644
index 534daa0..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/AbstractOpenFlowSwitch.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/**
- * Copyright 2011, Big Switch Networks, Inc.
- * Originally created by David Erickson, Stanford University
- *
- * 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.of.controller.impl.internal;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.jboss.netty.channel.Channel;
-import org.onlab.onos.of.controller.Dpid;
-import org.onlab.onos.of.controller.OpenFlowSwitch;
-import org.onlab.onos.of.controller.RoleState;
-import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent;
-import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleRecvStatus;
-import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleReplyInfo;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFErrorMsg;
-import org.projectfloodlight.openflow.protocol.OFExperimenter;
-import org.projectfloodlight.openflow.protocol.OFFactories;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFRoleReply;
-import org.projectfloodlight.openflow.protocol.OFVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
-
- private static Logger log =
- LoggerFactory.getLogger(AbstractOpenFlowSwitch.class);
-
- protected Channel channel;
- protected boolean startDriverHandshakeCalled = false;
-
- private boolean connected;
- private Dpid dpid;
- private OpenFlowSwitchAgent agent;
- private AtomicInteger xidCounter = new AtomicInteger(0);
-
- private OFVersion ofVersion;
-
- protected OFPortDescStatsReply ports;
-
- protected boolean tableFull;
-
- private final RoleManager roleMan = new RoleManager(this);
-
- protected RoleState role;
-
- protected OFFeaturesReply features;
-
- protected AbstractOpenFlowSwitch(Dpid dp) {
- this.dpid = dp;
- }
-
- //************************
- // Channel related
- //************************
-
- /**
- * Disconnects the switch by closing the TCP connection. Results in a call
- * to the channel handler's channelDisconnected method for cleanup
- * @throws IOException
- */
- public final void disconnectSwitch() {
- this.channel.close();
- }
-
- /**
- * Writes to the OFMessage to the output stream.
- *
- * @param m the message to be written
- */
- public abstract void sendMsg(OFMessage m);
-
- /**
- * Writes to the OFMessage list to the output stream.
- *
- * @param msgs the messages to be written
- */
- public void write(List<OFMessage> msgs) {
- this.channel.write(msgs);
- }
-
-
- /**
- * Checks if the switch is still connected.
- * Only call while holding processMessageLock
- *
- * @return whether the switch is still disconnected
- */
- public final boolean isConnected() {
- return this.connected;
- }
-
- /**
- * Sets whether the switch is connected.
- * Only call while holding modifySwitchLock
- *
- * @param connected whether the switch is connected
- */
- final void setConnected(boolean connected) {
- this.connected = connected;
- };
-
- /**
- * Sets the Netty Channel this switch instance is associated with.
- * <p>
- * Called immediately after instantiation
- *
- * @param channel the channel
- */
- public final void setChannel(Channel channel) {
- this.channel = channel;
- };
-
- //************************
- // Switch features related
- //************************
-
- /**
- * Gets the datapathId of the switch.
- *
- * @return the switch buffers
- */
- public final long getId() {
- return this.dpid.value();
- };
-
- /**
- * Gets a string version of the ID for this switch.
- *
- * @return string version of the ID
- */
- public final String getStringId() {
- return this.dpid.toString();
- }
-
- public final void setOFVersion(OFVersion ofV) {
- this.ofVersion = ofV;
- }
-
- void setTableFull(boolean full) {
- this.tableFull = full;
- }
-
- public void setFeaturesReply(OFFeaturesReply featuresReply) {
- this.features = featuresReply;
- }
-
- /**
- * Let peoeple know if you support Nicira style role requests.
- *
- * @return support Nicira roles or not.
- */
- public abstract Boolean supportNxRole();
-
- //************************
- // Message handling
- //************************
- /**
- * Handle the message coming from the dataplane.
- *
- * @param m the actual message
- */
- public final void handleMessage(OFMessage m) {
- this.agent.processMessage(m);
- }
-
- public RoleState getRole() {
- return role;
- };
-
- final boolean addConnectedSwitch() {
- return this.agent.addConnectedSwitch(this.getId(), this);
- }
-
- final boolean addActivatedMasterSwitch() {
- return this.agent.addActivatedMasterSwitch(this.getId(), this);
- }
-
- final boolean addActivatedEqualSwitch() {
- return this.agent.addActivatedEqualSwitch(this.getId(), this);
- }
-
- final void transitionToEqualSwitch() {
- this.agent.transitionToEqualSwitch(this.getId());
- }
-
- final void transitionToMasterSwitch() {
- this.agent.transitionToMasterSwitch(this.getId());
- }
-
- final void removeConnectedSwitch() {
- this.agent.removeConnectedSwitch(this.getId());
- }
-
- protected OFFactory factory() {
- return OFFactories.getFactory(ofVersion);
- }
-
- public void setPortDescReply(OFPortDescStatsReply portDescReply) {
- this.ports = portDescReply;
- }
-
- public abstract void startDriverHandshake();
-
- public abstract boolean isDriverHandshakeComplete();
-
- public abstract void processDriverHandshakeMessage(OFMessage m);
-
- public void setRole(RoleState role) {
- try {
- if (this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE)) {
- this.role = role;
- }
- } catch (IOException e) {
- log.error("Unable to write to switch {}.", this.dpid);
- }
- }
-
- // Role Handling
-
- void handleRole(OFMessage m) throws SwitchStateException {
- RoleReplyInfo rri = roleMan.extractOFRoleReply((OFRoleReply) m);
- RoleRecvStatus rrs = roleMan.deliverRoleReply(rri);
- if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
- if (rri.getRole() == RoleState.MASTER) {
- this.transitionToMasterSwitch();
- } else if (rri.getRole() == RoleState.EQUAL ||
- rri.getRole() == RoleState.MASTER) {
- this.transitionToEqualSwitch();
- }
- }
- }
-
- void handleNiciraRole(OFMessage m) throws SwitchStateException {
- RoleState r = this.roleMan.extractNiciraRoleReply((OFExperimenter) m);
- if (r == null) {
- // The message wasn't really a Nicira role reply. We just
- // dispatch it to the OFMessage listeners in this case.
- this.handleMessage(m);
- }
-
- RoleRecvStatus rrs = this.roleMan.deliverRoleReply(
- new RoleReplyInfo(r, null, m.getXid()));
- if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
- if (r == RoleState.MASTER) {
- this.transitionToMasterSwitch();
- } else if (r == RoleState.EQUAL ||
- r == RoleState.SLAVE) {
- this.transitionToEqualSwitch();
- }
- }
- }
-
- boolean handleRoleError(OFErrorMsg error) {
- try {
- return RoleRecvStatus.OTHER_EXPECTATION != this.roleMan.deliverError(error);
- } catch (SwitchStateException e) {
- this.disconnectSwitch();
- }
- return true;
- }
-
- void reassertRole() {
- if (this.getRole() == RoleState.MASTER) {
- this.setRole(RoleState.MASTER);
- }
- }
-
- void setAgent(OpenFlowSwitchAgent ag) {
- this.agent = ag;
- }
-
- public void setSwitchDescription(OFDescStatsReply desc) {
- // TODO Auto-generated method stub
- }
-
- protected int getNextTransactionId() {
- return this.xidCounter.getAndIncrement();
- }
-
- protected List<OFPortDesc> getPorts() {
- return Collections.unmodifiableList(ports.getEntries());
- }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java
index b88a9ec..ab9315f 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java
@@ -30,9 +30,10 @@
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.onlab.onos.of.controller.Dpid;
+import org.onlab.onos.of.controller.driver.OpenFlowAgent;
+import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
-import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent;
import org.onlab.onos.of.drivers.DriverManager;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFFactories;
@@ -74,7 +75,7 @@
// Flag to always flush flow table on switch reconnect (HA or otherwise)
protected boolean alwaysClearFlowsOnSwAdd = false;
- private OpenFlowSwitchAgent agent;
+ private OpenFlowAgent agent;
// Perf. related configuration
protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
@@ -120,17 +121,17 @@
* Tell controller that we're ready to accept switches loop.
*/
@LogMessageDocs({
- @LogMessageDoc(message = "Listening for switch connections on {address}",
- explanation = "The controller is ready and listening for new" +
- " switch connections"),
- @LogMessageDoc(message = "Storage exception in controller " +
- "updates loop; terminating process",
- explanation = ERROR_DATABASE,
- recommendation = LogMessageDoc.CHECK_CONTROLLER),
- @LogMessageDoc(level = "ERROR",
- message = "Exception in controller updates loop",
- explanation = "Failed to dispatch controller event",
- recommendation = LogMessageDoc.GENERIC_ACTION)
+ @LogMessageDoc(message = "Listening for switch connections on {address}",
+ explanation = "The controller is ready and listening for new" +
+ " switch connections"),
+ @LogMessageDoc(message = "Storage exception in controller " +
+ "updates loop; terminating process",
+ explanation = ERROR_DATABASE,
+ recommendation = LogMessageDoc.CHECK_CONTROLLER),
+ @LogMessageDoc(level = "ERROR",
+ message = "Exception in controller updates loop",
+ explanation = "Failed to dispatch controller event",
+ recommendation = LogMessageDoc.GENERIC_ACTION)
})
public void run() {
@@ -221,15 +222,16 @@
* @param desc
* @return switch instance
*/
- protected AbstractOpenFlowSwitch getOFSwitchInstance(long dpid,
+ protected OpenFlowSwitchDriver getOFSwitchInstance(long dpid,
OFDescStatsReply desc, OFVersion ofv) {
- AbstractOpenFlowSwitch sw = DriverManager.getOFSwitchImpl(new Dpid(dpid),
+ OpenFlowSwitchDriver sw = DriverManager.getSwitch(new Dpid(dpid),
desc, ofv);
sw.setAgent(agent);
+ sw.setRoleHandler(new RoleManager(sw));
return sw;
}
- public void start(OpenFlowSwitchAgent ag) {
+ public void start(OpenFlowAgent ag) {
log.info("Initialising OpenFlow Lib and IO");
this.agent = ag;
this.init(new HashMap<String, String>());
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java
index 4b2f7c3..035c4ca 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java
@@ -1,5 +1,6 @@
package org.onlab.onos.of.controller.impl.internal;
+import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
import org.projectfloodlight.openflow.protocol.OFVersion;
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java
index 23bc994..768362f 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java
@@ -18,6 +18,8 @@
import org.jboss.netty.handler.timeout.IdleStateEvent;
import org.jboss.netty.handler.timeout.ReadTimeoutException;
import org.onlab.onos.of.controller.RoleState;
+import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
+import org.onlab.onos.of.controller.driver.SwitchStateException;
import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
import org.projectfloodlight.openflow.exceptions.OFParseError;
@@ -66,7 +68,7 @@
class OFChannelHandler extends IdleStateAwareChannelHandler {
private static final Logger log = LoggerFactory.getLogger(OFChannelHandler.class);
private final Controller controller;
- private AbstractOpenFlowSwitch sw;
+ private OpenFlowSwitchDriver sw;
private long thisdpid; // channelHandler cached value of connected switch id
private Channel channel;
// State needs to be volatile because the HandshakeTimeoutHandler
@@ -413,7 +415,7 @@
OFDescStatsReply drep = (OFDescStatsReply) m;
// Here is where we differentiate between different kinds of switches
h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion);
- boolean success = h.sw.addConnectedSwitch();
+ boolean success = h.sw.connectSwitch();
if (!success) {
disconnectDuplicate(h);
return;
@@ -431,7 +433,7 @@
//Put switch in EQUAL mode until we hear back from the global registry
log.debug("Setting new switch {} to EQUAL and sending Role request",
h.sw.getStringId());
- h.sw.addActivatedEqualSwitch();
+ h.sw.activateEqualSwitch();
//h.setSwitchRole(RoleState.EQUAL);
h.setSwitchRole(RoleState.MASTER);
h.sw.startDriverHandshake();
@@ -489,8 +491,8 @@
}
}
} else {
- if (m.getType() == OFType.EXPERIMENTER &&
- ((OFExperimenter) m).getExperimenter() ==
+ if (m.getType() == OFType.EXPERIMENTER &&
+ ((OFExperimenter) m).getExperimenter() ==
RoleManager.NICIRA_EXPERIMENTER) {
h.sw.handleNiciraRole(m);
} else {
@@ -848,8 +850,8 @@
processOFQueueGetConfigReply(h, (OFQueueGetConfigReply) m);
break;
case STATS_REPLY: // multipart_reply in 1.3
- processOFStatisticsReply(h, (OFStatsReply) m);
- break;
+ processOFStatisticsReply(h, (OFStatsReply) m);
+ break;
case EXPERIMENTER:
processOFExperimenter(h, (OFExperimenter) m);
break;
@@ -916,12 +918,12 @@
}
OFFactory factory = (h.ofVersion == OFVersion.OF_13) ?
h.controller.getOFMessageFactory13() : h.controller.getOFMessageFactory10();
- OFEchoReply reply = factory
- .buildEchoReply()
- .setXid(m.getXid())
- .setData(m.getData())
- .build();
- h.channel.write(Collections.singletonList(reply));
+ OFEchoReply reply = factory
+ .buildEchoReply()
+ .setXid(m.getXid())
+ .setData(m.getData())
+ .build();
+ h.channel.write(Collections.singletonList(reply));
}
void processOFEchoReply(OFChannelHandler h, OFEchoReply m)
@@ -1044,41 +1046,41 @@
message = "Disconnecting switch {switch} due to read timeout",
explanation = "The connected switch has failed to send any "
+ "messages or respond to echo requests",
- recommendation = LogMessageDoc.CHECK_SWITCH),
+ recommendation = LogMessageDoc.CHECK_SWITCH),
@LogMessageDoc(level = "ERROR",
- message = "Disconnecting switch {switch}: failed to "
- + "complete handshake",
- explanation = "The switch did not respond correctly "
- + "to handshake messages",
- recommendation = LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level = "ERROR",
- message = "Disconnecting switch {switch} due to IO Error: {}",
- explanation = "There was an error communicating with the switch",
- recommendation = LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level = "ERROR",
- message = "Disconnecting switch {switch} due to switch "
- + "state error: {error}",
- explanation = "The switch sent an unexpected message",
- recommendation = LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level = "ERROR",
- message = "Disconnecting switch {switch} due to "
- + "message parse failure",
- explanation = "Could not parse a message from the switch",
- recommendation = LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level = "ERROR",
- message = "Terminating controller due to storage exception",
- explanation = Controller.ERROR_DATABASE,
- recommendation = LogMessageDoc.CHECK_CONTROLLER),
- @LogMessageDoc(level = "ERROR",
- message = "Could not process message: queue full",
- explanation = "OpenFlow messages are arriving faster than "
- + "the controller can process them.",
- recommendation = LogMessageDoc.CHECK_CONTROLLER),
- @LogMessageDoc(level = "ERROR",
- message = "Error while processing message "
- + "from switch {switch} {cause}",
- explanation = "An error occurred processing the switch message",
- recommendation = LogMessageDoc.GENERIC_ACTION)
+ message = "Disconnecting switch {switch}: failed to "
+ + "complete handshake",
+ explanation = "The switch did not respond correctly "
+ + "to handshake messages",
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Disconnecting switch {switch} due to IO Error: {}",
+ explanation = "There was an error communicating with the switch",
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Disconnecting switch {switch} due to switch "
+ + "state error: {error}",
+ explanation = "The switch sent an unexpected message",
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Disconnecting switch {switch} due to "
+ + "message parse failure",
+ explanation = "Could not parse a message from the switch",
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Terminating controller due to storage exception",
+ explanation = Controller.ERROR_DATABASE,
+ recommendation = LogMessageDoc.CHECK_CONTROLLER),
+ @LogMessageDoc(level = "ERROR",
+ message = "Could not process message: queue full",
+ explanation = "OpenFlow messages are arriving faster than "
+ + "the controller can process them.",
+ recommendation = LogMessageDoc.CHECK_CONTROLLER),
+ @LogMessageDoc(level = "ERROR",
+ message = "Error while processing message "
+ + "from switch {switch} {cause}",
+ explanation = "An error occurred processing the switch message",
+ recommendation = LogMessageDoc.GENERIC_ACTION)
})
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java
index f846e65..b7ba4c7 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java
@@ -15,8 +15,9 @@
import org.onlab.onos.of.controller.OpenFlowSwitchListener;
import org.onlab.onos.of.controller.PacketListener;
import org.onlab.onos.of.controller.RoleState;
+import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
+import org.onlab.onos.of.controller.driver.OpenFlowAgent;
import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -27,12 +28,12 @@
private static final Logger log =
LoggerFactory.getLogger(OpenFlowControllerImpl.class);
- protected ConcurrentHashMap<Long, OpenFlowSwitch> connectedSwitches =
- new ConcurrentHashMap<Long, OpenFlowSwitch>();
- protected ConcurrentHashMap<Long, OpenFlowSwitch> activeMasterSwitches =
- new ConcurrentHashMap<Long, OpenFlowSwitch>();
- protected ConcurrentHashMap<Long, OpenFlowSwitch> activeEqualSwitches =
- new ConcurrentHashMap<Long, OpenFlowSwitch>();
+ protected ConcurrentHashMap<Dpid, OpenFlowSwitch> connectedSwitches =
+ new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
+ protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeMasterSwitches =
+ new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
+ protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeEqualSwitches =
+ new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
protected ArrayList<OpenFlowSwitchListener> ofEventListener =
@@ -118,12 +119,13 @@
((AbstractOpenFlowSwitch) getSwitch(dpid)).setRole(role);
}
- public class OpenFlowSwitchAgent {
+ public class OpenFlowSwitchAgent implements OpenFlowAgent {
private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
- private Lock switchLock = new ReentrantLock();
+ private final Lock switchLock = new ReentrantLock();
- public boolean addConnectedSwitch(long dpid, AbstractOpenFlowSwitch sw) {
+ @Override
+ public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
if (connectedSwitches.get(dpid) != null) {
log.error("Trying to add connectedSwitch but found a previous "
+ "value for dpid: {}", dpid);
@@ -132,17 +134,18 @@
log.error("Added switch {}", dpid);
connectedSwitches.put(dpid, sw);
for (OpenFlowSwitchListener l : ofEventListener) {
- l.switchAdded(new Dpid(dpid));
+ l.switchAdded(dpid);
}
return true;
}
}
- private boolean validActivation(long dpid) {
+ @Override
+ public boolean validActivation(Dpid dpid) {
if (connectedSwitches.get(dpid) == null) {
log.error("Trying to activate switch but is not in "
+ "connected switches: dpid {}. Aborting ..",
- HexString.toHexString(dpid));
+ dpid);
return false;
}
if (activeMasterSwitches.get(dpid) != null ||
@@ -150,18 +153,17 @@
log.error("Trying to activate switch but it is already "
+ "activated: dpid {}. Found in activeMaster: {} "
+ "Found in activeEqual: {}. Aborting ..", new Object[] {
- HexString.toHexString(dpid),
+ dpid,
(activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
- (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
+ (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
return false;
}
return true;
}
- /**
- * Called when a switch is activated, with this controller's role as MASTER.
- */
- protected boolean addActivatedMasterSwitch(long dpid, AbstractOpenFlowSwitch sw) {
+
+ @Override
+ public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) {
switchLock.lock();
try {
if (!validActivation(dpid)) {
@@ -172,31 +174,25 @@
} finally {
switchLock.unlock();
}
- }
+ }
- /**
- * Called when a switch is activated, with this controller's role as EQUAL.
- */
- protected boolean addActivatedEqualSwitch(long dpid, AbstractOpenFlowSwitch sw) {
+ @Override
+ public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) {
switchLock.lock();
try {
- if (!validActivation(dpid)) {
- return false;
- }
- activeEqualSwitches.put(dpid, sw);
- log.info("Added Activated EQUAL Switch {}", dpid);
- return true;
+ if (!validActivation(dpid)) {
+ return false;
+ }
+ activeEqualSwitches.put(dpid, sw);
+ log.info("Added Activated EQUAL Switch {}", dpid);
+ return true;
} finally {
switchLock.unlock();
}
}
- /**
- * Called when this controller's role for a switch transitions from equal
- * to master. For 1.0 switches, we internally refer to the role 'slave' as
- * 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'.
- */
- protected void transitionToMasterSwitch(long dpid) {
+ @Override
+ public void transitionToMasterSwitch(Dpid dpid) {
switchLock.lock();
try {
if (activeMasterSwitches.containsKey(dpid)) {
@@ -215,12 +211,8 @@
}
- /**
- * Called when this controller's role for a switch transitions to equal.
- * For 1.0 switches, we internally refer to the role 'slave' as
- * 'equal'.
- */
- protected void transitionToEqualSwitch(long dpid) {
+ @Override
+ public void transitionToEqualSwitch(Dpid dpid) {
switchLock.lock();
try {
if (activeEqualSwitches.containsKey(dpid)) {
@@ -239,22 +231,19 @@
}
- /**
- * Clear all state in controller switch maps for a switch that has
- * disconnected from the local controller. Also release control for
- * that switch from the global repository. Notify switch listeners.
- */
- public void removeConnectedSwitch(long dpid) {
+ @Override
+ public void removeConnectedSwitch(Dpid dpid) {
connectedSwitches.remove(dpid);
OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
if (sw == null) {
sw = activeEqualSwitches.remove(dpid);
}
for (OpenFlowSwitchListener l : ofEventListener) {
- l.switchRemoved(new Dpid(dpid));
+ l.switchRemoved(dpid);
}
}
+ @Override
public void processMessage(OFMessage m) {
processPacket(m);
}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java
index 99e9173..235eb61 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java
@@ -4,6 +4,11 @@
import java.util.Collections;
import org.onlab.onos.of.controller.RoleState;
+import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
+import org.onlab.onos.of.controller.driver.RoleHandler;
+import org.onlab.onos.of.controller.driver.RoleRecvStatus;
+import org.onlab.onos.of.controller.driver.RoleReplyInfo;
+import org.onlab.onos.of.controller.driver.SwitchStateException;
import org.projectfloodlight.openflow.protocol.OFControllerRole;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFErrorType;
@@ -35,7 +40,7 @@
* a new request is submitted before the timeout triggers. If necessary
* we could work around that though.
*/
-class RoleManager {
+class RoleManager implements RoleHandler {
protected static final long NICIRA_EXPERIMENTER = 0x2320;
private static Logger log = LoggerFactory.getLogger(RoleManager.class);
@@ -49,10 +54,10 @@
// the expectation set by the caller for the returned role
private RoleRecvStatus expectation;
- private AbstractOpenFlowSwitch sw;
+ private final OpenFlowSwitchDriver sw;
- public RoleManager(AbstractOpenFlowSwitch sw) {
+ public RoleManager(OpenFlowSwitchDriver sw) {
this.requestPending = false;
this.pendingXid = -1;
this.pendingRole = null;
@@ -122,33 +127,13 @@
return xid;
}
- /**
- * Send a role request with the given role to the switch and update
- * the pending request and timestamp.
- * Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR
- * Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it
- * in the IOFSwitch driver. If not supported, this method sends nothing
- * and returns 'false'. The caller should take appropriate action.
- *
- * One other optimization we do here is that for OF1.0 switches with
- * Nicira role message support, we force the Role.EQUAL to become
- * Role.SLAVE, as there is no defined behavior for the Nicira role OTHER.
- * We cannot expect it to behave like SLAVE. We don't have this problem with
- * OF1.3 switches, because Role.EQUAL is well defined and we can simulate
- * SLAVE behavior by using ASYNC messages.
- *
- * @param role
- * @throws IOException
- * @returns false if and only if the switch does not support role-request
- * messages, according to the switch driver; true otherwise.
- */
- synchronized boolean sendRoleRequest(RoleState role, RoleRecvStatus exp)
+ @Override
+ public synchronized boolean sendRoleRequest(RoleState role, RoleRecvStatus exp)
throws IOException {
this.expectation = exp;
if (sw.factory().getVersion() == OFVersion.OF_10) {
- Boolean supportsNxRole = (Boolean)
- sw.supportNxRole();
+ Boolean supportsNxRole = sw.supportNxRole();
if (!supportsNxRole) {
log.debug("Switch driver indicates no support for Nicira "
+ "role request messages. Not sending ...");
@@ -189,23 +174,9 @@
}
- /**
- * Deliver a received role reply.
- *
- * Check if a request is pending and if the received reply matches the
- * the expected pending reply (we check both role and xid) we set
- * the role for the switch/channel.
- *
- * If a request is pending but doesn't match the reply we ignore it, and
- * return
- *
- * If no request is pending we disconnect with a SwitchStateException
- *
- * @param RoleReplyInfo information about role-reply in format that
- * controller can understand.
- * @throws SwitchStateException if no request is pending
- */
- synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
+
+ @Override
+ public synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
throws SwitchStateException {
if (!requestPending) {
RoleState currentRole = (sw != null) ? sw.getRole() : null;
@@ -280,12 +251,13 @@
* error messages for earlier role requests that we won't be able
* to handle
*/
- synchronized RoleRecvStatus deliverError(OFErrorMsg error)
+ @Override
+ public synchronized RoleRecvStatus deliverError(OFErrorMsg error)
throws SwitchStateException {
if (!requestPending) {
log.debug("Received an error msg from sw {}, but no pending "
+ "requests in role-changer; not handling ...",
- sw.getStringId());
+ sw.getStringId());
return RoleRecvStatus.OTHER_EXPECTATION;
}
if (pendingXid != error.getXid()) {
@@ -353,7 +325,8 @@
* @throws SwitchStateException If the message is a Nicira role reply
* but the numeric role value is unknown.
*/
- protected RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg)
+ @Override
+ public RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg)
throws SwitchStateException {
int vendor = (int) experimenterMsg.getExperimenter();
if (vendor != 0x2320) {
@@ -389,72 +362,14 @@
}
/**
- * When we remove a pending role request we use this enum to indicate how we
- * arrived at the decision. When we send a role request to the switch, we
- * also use this enum to indicate what we expect back from the switch, so the
- * role changer can match the reply to our expectation.
- */
- public enum RoleRecvStatus {
- /** The switch returned an error indicating that roles are not.
- * supported*/
- UNSUPPORTED,
- /** The request timed out. */
- NO_REPLY,
- /** The reply was old, there is a newer request pending. */
- OLD_REPLY,
- /**
- * The reply's role matched the role that this controller set in the
- * request message - invoked either initially at startup or to reassert
- * current role.
- */
- MATCHED_CURRENT_ROLE,
- /**
- * The reply's role matched the role that this controller set in the
- * request message - this is the result of a callback from the
- * global registry, followed by a role request sent to the switch.
- */
- MATCHED_SET_ROLE,
- /**
- * The reply's role was a response to the query made by this controller.
- */
- REPLY_QUERY,
- /** We received a role reply message from the switch
- * but the expectation was unclear, or there was no expectation.
- */
- OTHER_EXPECTATION,
- }
-
- /**
- * Helper class returns role reply information in the format understood
- * by the controller.
- */
- protected static class RoleReplyInfo {
- private RoleState role;
- private U64 genId;
- private long xid;
-
- RoleReplyInfo(RoleState role, U64 genId, long xid) {
- this.role = role;
- this.genId = genId;
- this.xid = xid;
- }
- public RoleState getRole() { return role; }
- public U64 getGenId() { return genId; }
- public long getXid() { return xid; }
- @Override
- public String toString() {
- return "[Role:" + role + " GenId:" + genId + " Xid:" + xid + "]";
- }
- }
-
- /**
* Extract the role information from an OF1.3 Role Reply Message.
* @param h
- * @param rrmsg
+ * @param rrmsg the role message
* @return RoleReplyInfo object
- * @throws SwitchStateException
+ * @throws SwitchStateException if the role information could not be extracted.
*/
- protected RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg)
+ @Override
+ public RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg)
throws SwitchStateException {
OFControllerRole cr = rrmsg.getRole();
RoleState role = null;
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeAlreadyStarted.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeAlreadyStarted.java
deleted file mode 100644
index 53227aa..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeAlreadyStarted.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.onlab.onos.of.controller.impl.internal;
-
-/**
- * Thrown when IOFSwitch.startDriverHandshake() is called more than once.
- *
- */
-public class SwitchDriverSubHandshakeAlreadyStarted extends
- SwitchDriverSubHandshakeException {
- private static final long serialVersionUID = -5491845708752443501L;
-
- public SwitchDriverSubHandshakeAlreadyStarted() {
- super();
- }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeCompleted.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeCompleted.java
deleted file mode 100644
index ba792e5..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeCompleted.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.onlab.onos.of.controller.impl.internal;
-
-import org.projectfloodlight.openflow.protocol.OFMessage;
-
-
-/**
- * Indicates that a message was passed to a switch driver's subhandshake
- * handling code but the driver has already completed the sub-handshake.
- *
- */
-public class SwitchDriverSubHandshakeCompleted
- extends SwitchDriverSubHandshakeException {
- private static final long serialVersionUID = -8817822245846375995L;
-
- public SwitchDriverSubHandshakeCompleted(OFMessage m) {
- super("Sub-Handshake is already complete but received message "
- + m.getType());
- }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeException.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeException.java
deleted file mode 100644
index 49fdead..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.onlab.onos.of.controller.impl.internal;
-
-/**
- * Base class for exception thrown by switch driver sub-handshake processing.
- *
- */
-public class SwitchDriverSubHandshakeException extends RuntimeException {
- private static final long serialVersionUID = -6257836781419604438L;
-
- protected SwitchDriverSubHandshakeException() {
- super();
- }
-
- protected SwitchDriverSubHandshakeException(String arg0, Throwable arg1) {
- super(arg0, arg1);
- }
-
- protected SwitchDriverSubHandshakeException(String arg0) {
- super(arg0);
- }
-
- protected SwitchDriverSubHandshakeException(Throwable arg0) {
- super(arg0);
- }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeNotStarted.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeNotStarted.java
deleted file mode 100644
index 72b17dc..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeNotStarted.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.onlab.onos.of.controller.impl.internal;
-
-/**
- * Thrown when a switch driver's sub-handshake has not been started but an
- * operation requiring the sub-handshake has been attempted.
- *
- */
-public class SwitchDriverSubHandshakeNotStarted extends
- SwitchDriverSubHandshakeException {
- private static final long serialVersionUID = -5491845708752443501L;
-
- public SwitchDriverSubHandshakeNotStarted() {
- super();
- }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeStateException.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeStateException.java
deleted file mode 100644
index 191d1bb..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeStateException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.onlab.onos.of.controller.impl.internal;
-
-/**
- * Thrown when a switch driver's sub-handshake state-machine receives an
- * unexpected OFMessage and/or is in an invald state.
- *
- */
-public class SwitchDriverSubHandshakeStateException extends
- SwitchDriverSubHandshakeException {
- private static final long serialVersionUID = -8249926069195147051L;
-
- public SwitchDriverSubHandshakeStateException(String msg) {
- super(msg);
- }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchStateException.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchStateException.java
deleted file mode 100644
index d82e917..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchStateException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Copyright 2011, Big Switch Networks, Inc.
- * Originally created by David Erickson, Stanford University
- *
- * 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.of.controller.impl.internal;
-
-/**
- * This exception indicates an error or unexpected message during
- * message handling. E.g., if an OFMessage is received that is illegal or
- * unexpected given the current handshake state.
- *
- * We don't allow wrapping other exception in a switch state exception. We
- * only log the SwitchStateExceptions message so the causing exceptions
- * stack trace is generally not available.
- *
- */
-public class SwitchStateException extends Exception {
-
- private static final long serialVersionUID = 9153954512470002631L;
-
- public SwitchStateException() {
- super();
- }
-
- public SwitchStateException(String arg0, Throwable arg1) {
- super(arg0, arg1);
- }
-
- public SwitchStateException(String arg0) {
- super(arg0);
- }
-
- public SwitchStateException(Throwable arg0) {
- super(arg0);
- }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/drivers/DriverManager.java b/of/ctl/src/main/java/org/onlab/onos/of/drivers/DriverManager.java
index b475c91..97f94d3 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/drivers/DriverManager.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/drivers/DriverManager.java
@@ -3,11 +3,9 @@
import org.onlab.onos.of.controller.Dpid;
-import org.onlab.onos.of.controller.RoleState;
-import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch;
+import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
+import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriverFactory;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -16,7 +14,7 @@
* A simple implementation of a driver manager that differentiates between
* connected switches using the OF Description Statistics Reply message.
*/
-public final class DriverManager {
+public final class DriverManager implements OpenFlowSwitchDriverFactory {
private static final Logger log = LoggerFactory.getLogger(DriverManager.class);
@@ -32,7 +30,8 @@
* @return A IOFSwitch instance if the driver found an implementation for
* the given description. Otherwise it returns OFSwitchImplBase
*/
- public static AbstractOpenFlowSwitch getOFSwitchImpl(Dpid dpid,
+ @Override
+ public OpenFlowSwitchDriver getOFSwitchImpl(Dpid dpid,
OFDescStatsReply desc, OFVersion ofv) {
String vendor = desc.getMfrDesc();
String hw = desc.getHwDesc();
@@ -53,42 +52,7 @@
log.warn("DriverManager could not identify switch desc: {}. "
+ "Assigning OFSwitchImplBase", desc);
- AbstractOpenFlowSwitch base = new AbstractOpenFlowSwitch(dpid) {
-
-
- @Override
- public void sendMsg(OFMessage m) {
- channel.write(m);
- }
-
- @Override
- public Boolean supportNxRole() {
- return false;
- }
-
- @Override
- public void startDriverHandshake() {}
-
- @Override
- public void setFeaturesReply(OFFeaturesReply featuresReply) {
- this.features = featuresReply;
- }
-
- @Override
- public void processDriverHandshakeMessage(OFMessage m) {}
-
- @Override
- public boolean isDriverHandshakeComplete() {
- return true;
- }
-
- @Override
- public RoleState getRole() {
- return role;
- }
- };
- base.setSwitchDescription(desc);
- return base;
+ return null;
}
/**
@@ -108,4 +72,10 @@
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/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplCPqD13.java b/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplCPqD13.java
index 6f78e8f..b2881ba 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplCPqD13.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplCPqD13.java
@@ -10,15 +10,14 @@
import org.onlab.onos.of.controller.Dpid;
import org.onlab.onos.of.controller.RoleState;
-import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch;
-import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeCompleted;
-import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeNotStarted;
+import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
+import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
+import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeCompleted;
+import org.onlab.onos.of.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.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFGroupFeaturesStatsReply;
@@ -61,11 +60,11 @@
*/
public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
- private Logger log =
+ private final Logger log =
LoggerFactory.getLogger(OFSwitchImplCPqD13.class);
private static final int VLAN_ID_OFFSET = 16;
- private AtomicBoolean driverHandshakeComplete;
+ private final AtomicBoolean driverHandshakeComplete;
private OFFactory factory;
private static final int OFPCML_NO_BUFFER = 0xffff;
// Configuration of asynch messages to controller. We need different
@@ -96,7 +95,7 @@
private static final short MIN_PRIORITY = 0x0;
private static final U64 METADATA_MASK = U64.of(Long.MAX_VALUE << 1 | 0x1);
- private Map<Integer, OFGroup> l2groups;
+ private final Map<Integer, OFGroup> l2groups;
private final boolean usePipeline13;
@@ -131,7 +130,7 @@
// Send packet-in to controller if a packet misses the first table
populateTableMissEntry(0, true, false, false, 0);
} //else {
- // configureSwitch();
+ // configureSwitch();
//}
sendBarrier(true);
}
@@ -146,14 +145,7 @@
@Override
public void processDriverHandshakeMessage(OFMessage m) {
- if (!startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeNotStarted();
- }
- if (driverHandshakeComplete.get()) {
- throw new SwitchDriverSubHandshakeCompleted(m);
- }
-
- if (!startDriverHandshakeCalled) {
+ if (!startDriverHandshakeCalled || !startDriverHandshakeCalled) {
throw new SwitchDriverSubHandshakeNotStarted();
}
if (driverHandshakeComplete.get()) {
@@ -168,30 +160,23 @@
break;
case ERROR:
- log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m);
+ 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;
+ 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 "
@@ -254,7 +239,7 @@
.build();
msglist.add(getAC);
- write(msglist);
+ sendMsg(msglist);
}
private void decodeAsyncGetReply(OFAsyncGetReply rep) {
@@ -327,7 +312,7 @@
}
}
log.debug("Creating {} L2 groups in sw {}", msglist.size(), getStringId());
- write(msglist);
+ sendMsg(msglist);
}
private int getVlanConfig(int portnum) {
@@ -405,9 +390,9 @@
List<OFAction> actions = new ArrayList<OFAction>();
actions.add(decTtl); // decrement the IP TTL/do-checksum/check TTL
- // and MTU
+ // and MTU
actions.add(setVlan); // set the vlan-id of the exit-port (and
- // l2group)
+ // l2group)
actions.add(setSA); // set this routers mac address
// make L3Unicast group setDA for known (configured) ports
// that connect to other routers
@@ -428,7 +413,7 @@
.build();
msglist.add(gmAdd);
}
- write(msglist);
+ sendMsg(msglist);
log.debug("Creating {} L3 groups in sw {}", msglist.size(), getStringId());
}
@@ -449,8 +434,8 @@
// 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
+ // for mpls
+ // group
OFAction group = factory.actions().buildGroup()
.setGroup(gl2).build();
OFOxmEthSrc srcAddr = factory.oxms().ethSrc(sAddr);
@@ -462,9 +447,9 @@
OFAction decMplsTtl = factory.actions().decMplsTtl();
List<OFAction> actions = new ArrayList<OFAction>();
actions.add(decMplsTtl); // decrement the MPLS
- // TTL/do-checksum/check TTL and MTU
+ // TTL/do-checksum/check TTL and MTU
actions.add(setVlan); // set the vlan-id of the exit-port (and
- // l2group)
+ // l2group)
actions.add(setSA); // set this routers mac address
actions.add(setDA);
actions.add(group);
@@ -480,7 +465,7 @@
msglist.add(gmAdd);
}
}
- write(msglist);
+ sendMsg(msglist);
log.debug("Creating {} MPLS groups in sw {}", msglist.size(), getStringId());
}
@@ -586,7 +571,7 @@
.setMatch(match)
.setInstructions(instructions)
.setPriority(1000) // does not matter - all rules
- // exclusive
+ // exclusive
.setBufferId(OFBufferId.NO_BUFFER)
.setIdleTimeout(0)
.setHardTimeout(0)
@@ -597,7 +582,7 @@
}
// table-vlan has no table-miss entry, and so packets that miss are
// essentially dropped
- write(msglist);
+ sendMsg(msglist);
log.debug("Adding {} vlan-rules in sw {}", msglist.size(), getStringId());
}
@@ -615,7 +600,7 @@
.setMatch(matchIp)
.setInstructions(instructionsIp)
.setPriority(1000) // strict priority required lower than
- // multicastMac
+ // multicastMac
.setBufferId(OFBufferId.NO_BUFFER)
.setIdleTimeout(0)
.setHardTimeout(0)
@@ -635,7 +620,7 @@
.setMatch(matchMpls)
.setInstructions(instructionsMpls)
.setPriority(1001) // strict priority required lower than
- // multicastMac
+ // multicastMac
.setBufferId(OFBufferId.NO_BUFFER)
.setIdleTimeout(0)
.setHardTimeout(0)
@@ -649,7 +634,7 @@
List<OFMessage> msglist = new ArrayList<OFMessage>(2);
msglist.add(ipEntry);
msglist.add(mplsEntry);
- write(msglist);
+ sendMsg(msglist);
}
private List<String> getMyIps() { // send to controller
@@ -712,13 +697,13 @@
List<RouteEntry> routerNextHopIps = new ArrayList<RouteEntry>();
if (getId() == 0x1) {
routerNextHopIps
- .add(new RouteEntry("192.168.0.2", "255.255.255.255", 6, 102));
+ .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));
+ .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.
+ /* 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));
@@ -728,9 +713,9 @@
//}
if (getId() == 0x3) {
routerNextHopIps
- .add(new RouteEntry("192.168.0.2", "255.255.255.255", 2, 102));
+ .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));
+ .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));
@@ -794,7 +779,7 @@
.setMatch(match)
.setInstructions(instructions)
.setPriority(MAX_PRIORITY) // highest priority for exact
- // match
+ // match
.setBufferId(OFBufferId.NO_BUFFER)
.setIdleTimeout(0)
.setHardTimeout(0)
@@ -802,7 +787,7 @@
.build();
msglist.add(myIpEntry);
}
- write(msglist);
+ sendMsg(msglist);
log.debug("Adding {} my-ip-rules in sw {}", msglist.size(), getStringId());
}
@@ -844,7 +829,7 @@
.build();
msglist.add(myIpEntry);
}
- write(msglist);
+ sendMsg(msglist);
log.debug("Adding {} subnet-ip-rules in sw {}", msglist.size(), getStringId());
msglist.clear();
}
@@ -861,14 +846,14 @@
.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();
+ .build();
// lots of actions before forwarding to mpls group, and
// unfortunately
// they need to be apply-actions
@@ -887,7 +872,7 @@
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);
@@ -896,7 +881,7 @@
.setActions(applyActions).build();
List<OFAction> writeActions = new ArrayList<OFAction>();
writeActions.add(outg); // group will decr mpls-ttl, set mac-sa/da,
- // vlan
+ // vlan
OFInstruction writeInstr = factory.instructions().buildWriteActions()
.setActions(writeActions).build();
@@ -950,7 +935,7 @@
OFAction outg2 = factory.actions().buildGroup()
.setGroup(OFGroup.of(routerNextHopIps.get(i).nextHopPort |
(192 << VLAN_ID_OFFSET)))
- .build();
+ .build();
writeActions2.add(outg2);
OFInstruction writeInstr2 = factory.instructions().buildWriteActions()
.setActions(writeActions2).build();
@@ -989,7 +974,7 @@
msglist.add(myMetaEntry);
}
- write(msglist);
+ sendMsg(msglist);
log.debug("Adding {} next-hop-router-rules in sw {}", msglist.size(),
getStringId());
@@ -1022,7 +1007,7 @@
.setField(dmac).build();
outg = factory.actions().buildGroup()
.setGroup(OFGroup.of(0x20000000 | hostNextHopIps.get(i).nextHopPort)) // l3group
- // id
+ // id
.build();
List<OFAction> writeActions = new ArrayList<OFAction>();
writeActions.add(setDmac);
@@ -1039,7 +1024,7 @@
.setMatch(match)
.setInstructions(instructions)
.setPriority(MAX_PRIORITY) // highest priority for exact
- // match
+ // match
.setBufferId(OFBufferId.NO_BUFFER)
.setIdleTimeout(0)
.setHardTimeout(0)
@@ -1047,7 +1032,7 @@
.build();
msglist.add(myIpEntry);
}
- write(msglist);
+ sendMsg(msglist);
log.debug("Adding {} next-hop-host-rules in sw {}", msglist.size(), getStringId());
}
@@ -1121,7 +1106,7 @@
.build();
msglist.add(myMplsEntry);
}
- write(msglist);
+ sendMsg(msglist);
log.debug("Adding {} mpls-forwarding-rules in sw {}", msglist.size(),
getStringId());
@@ -1190,7 +1175,7 @@
// 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 = (List<OFInstruction>) Collections.EMPTY_LIST;
+ instructions = Collections.EMPTY_LIST;
}
OFMessage tableMissEntry = factory.buildFlowAdd()
@@ -1219,20 +1204,19 @@
}
@Override
- public void sendMsg(OFMessage m) {
- channel.write(m);
+ public Boolean supportNxRole() {
+ return false;
+ }
+
+ @Override
+ public void write(OFMessage msg) {
+ this.channel.write(msg);
+
}
@Override
public void write(List<OFMessage> msgs) {
- for (OFMessage m : msgs) {
- channel.write(m);
- }
- }
-
- @Override
- public Boolean supportNxRole() {
- return false;
+ this.channel.write(msgs);
}
}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS10.java b/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS10.java
index 45228dc..bc42636 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS10.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS10.java
@@ -1,7 +1,9 @@
package org.onlab.onos.of.drivers;
+import java.util.List;
+
import org.onlab.onos.of.controller.Dpid;
-import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch;
+import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFMessage;
@@ -29,11 +31,6 @@
}
@Override
- public void sendMsg(OFMessage m) {
- channel.write(m);
- }
-
- @Override
public Boolean supportNxRole() {
return true;
}
@@ -48,4 +45,15 @@
@Override
public void processDriverHandshakeMessage(OFMessage m) {}
+
+ @Override
+ public void write(OFMessage msg) {
+ channel.write(msg);
+
+ }
+
+ @Override
+ public void write(List<OFMessage> msgs) {
+ channel.write(msgs);
+ }
}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS13.java b/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS13.java
index 1ab1f047..40750f7 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS13.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS13.java
@@ -1,15 +1,15 @@
package org.onlab.onos.of.drivers;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.onlab.onos.of.controller.Dpid;
-import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch;
-import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeCompleted;
-import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeNotStarted;
+import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
+import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
+import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeCompleted;
+import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeNotStarted;
import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.slf4j.Logger;
@@ -25,7 +25,7 @@
private static Logger log =
LoggerFactory.getLogger(OFSwitchImplOVS13.class);
- private AtomicBoolean driverHandshakeComplete;
+ private final AtomicBoolean driverHandshakeComplete;
private OFFactory factory;
private long barrierXidToWaitFor = -1;
@@ -78,7 +78,7 @@
break;
case ERROR:
- log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m);
+ log.error("Switch {} Error {}", getStringId(), m);
break;
case FEATURES_REPLY:
@@ -129,12 +129,18 @@
}
@Override
- public void sendMsg(OFMessage m) {
- channel.write(m);
+ public Boolean supportNxRole() {
+ return false;
}
@Override
- public Boolean supportNxRole() {
- return false;
+ public void write(OFMessage msg) {
+ channel.write(msg);
+
+ }
+
+ @Override
+ public void write(List<OFMessage> msgs) {
+ channel.write(msgs);
}
}