switch can now connect
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
index 7f4830d..534daa0 100644
--- 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
@@ -18,7 +18,9 @@
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;
@@ -27,12 +29,14 @@
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;
@@ -45,10 +49,13 @@
private static Logger log =
LoggerFactory.getLogger(AbstractOpenFlowSwitch.class);
- private Channel channel;
+ 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;
@@ -58,8 +65,12 @@
private final RoleManager roleMan = new RoleManager(this);
- protected AbstractOpenFlowSwitch(long dpid) {
- this.dpid = new Dpid(dpid);
+ protected RoleState role;
+
+ protected OFFeaturesReply features;
+
+ protected AbstractOpenFlowSwitch(Dpid dp) {
+ this.dpid = dp;
}
//************************
@@ -80,14 +91,16 @@
*
* @param m the message to be written
*/
- public abstract void write(OFMessage m);
+ public abstract void sendMsg(OFMessage m);
/**
* Writes to the OFMessage list to the output stream.
*
* @param msgs the messages to be written
*/
- public abstract void write(List<OFMessage> msgs);
+ public void write(List<OFMessage> msgs) {
+ this.channel.write(msgs);
+ }
/**
@@ -151,7 +164,9 @@
this.tableFull = full;
}
- public abstract void setFeaturesReply(OFFeaturesReply featuresReply);
+ public void setFeaturesReply(OFFeaturesReply featuresReply) {
+ this.features = featuresReply;
+ }
/**
* Let peoeple know if you support Nicira style role requests.
@@ -172,7 +187,9 @@
this.agent.processMessage(m);
}
- public abstract RoleState getRole();
+ public RoleState getRole() {
+ return role;
+ };
final boolean addConnectedSwitch() {
return this.agent.addConnectedSwitch(this.getId(), this);
@@ -214,7 +231,9 @@
public void setRole(RoleState role) {
try {
- this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE);
+ if (this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE)) {
+ this.role = role;
+ }
} catch (IOException e) {
log.error("Unable to write to switch {}.", this.dpid);
}
@@ -236,23 +255,23 @@
}
void handleNiciraRole(OFMessage m) throws SwitchStateException {
- RoleState role = this.roleMan.extractNiciraRoleReply((OFExperimenter) m);
- if (role == null) {
- // The message wasn't really a Nicira role reply. We just
- // dispatch it to the OFMessage listeners in this case.
- this.handleMessage(m);
- }
+ 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(role, null, m.getXid()));
- if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
- if (role == RoleState.MASTER) {
- this.transitionToMasterSwitch();
- } else if (role == RoleState.EQUAL ||
- role == RoleState.SLAVE) {
- this.transitionToEqualSwitch();
- }
- }
+ 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) {
@@ -274,6 +293,16 @@
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 6ae3abb..b88a9ec 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
@@ -29,9 +29,11 @@
import org.jboss.netty.channel.group.ChannelGroup;
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.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;
import org.projectfloodlight.openflow.protocol.OFFactory;
@@ -83,11 +85,6 @@
// Getters/Setters
// ***************
-
- public synchronized void setIOFSwitchManager(IOFSwitchManager swManager) {
- this.switchManager = swManager;
- }
-
public OFFactory getOFMessageFactory10() {
return FACTORY10;
}
@@ -201,18 +198,6 @@
}
- /**
- * Startup all of the controller's components.
- */
- @LogMessageDoc(message = "Waiting for storage source",
- explanation = "The system database is not yet ready",
- recommendation = "If this message persists, this indicates " +
- "that the system database has failed to start. " +
- LogMessageDoc.CHECK_CONTROLLER)
- public synchronized void startupComponents() {
- //TODO do something maybe
- }
-
// **************
// Utility methods
// **************
@@ -236,9 +221,10 @@
* @param desc
* @return switch instance
*/
- protected AbstractOpenFlowSwitch getOFSwitchInstance(OFDescStatsReply desc, OFVersion ofv) {
- AbstractOpenFlowSwitch sw = switchManager.getSwitchImpl(desc.getMfrDesc(), desc.getHwDesc(),
- desc.getSwDesc(), ofv);
+ protected AbstractOpenFlowSwitch getOFSwitchInstance(long dpid,
+ OFDescStatsReply desc, OFVersion ofv) {
+ AbstractOpenFlowSwitch sw = DriverManager.getOFSwitchImpl(new Dpid(dpid),
+ desc, ofv);
sw.setAgent(agent);
return sw;
}
@@ -247,7 +233,6 @@
log.info("Initialising OpenFlow Lib and IO");
this.agent = ag;
this.init(new HashMap<String, String>());
- this.startupComponents();
this.run();
}
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 5db1fc3..f4185e8 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
@@ -230,12 +230,6 @@
h.thisdpid = m.getDatapathId().getLong();
log.info("Received features reply for switch at {} with dpid {}",
h.getSwitchInfoString(), h.thisdpid);
- //update the controller about this connected switch
- boolean success = h.sw.addConnectedSwitch();
- if (!success) {
- disconnectDuplicate(h);
- return;
- }
h.featuresReply = m; //temp store
if (h.ofVersion == OFVersion.OF_10) {
@@ -419,7 +413,12 @@
h.channel.getRemoteAddress());
OFDescStatsReply drep = (OFDescStatsReply) m;
// Here is where we differentiate between different kinds of switches
- h.sw = h.controller.getOFSwitchInstance(drep, h.ofVersion);
+ h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion);
+ boolean success = h.sw.addConnectedSwitch();
+ if (!success) {
+ disconnectDuplicate(h);
+ return;
+ }
// set switch information
h.sw.setOFVersion(h.ofVersion);
h.sw.setFeaturesReply(h.featuresReply);
@@ -433,7 +432,9 @@
//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.setSwitchRole(RoleState.EQUAL);
+ h.sw.addActivatedEqualSwitch();
+ //h.setSwitchRole(RoleState.EQUAL);
+ h.setSwitchRole(RoleState.MASTER);
h.sw.startDriverHandshake();
h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
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 976e347..f846e65 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
@@ -24,12 +24,19 @@
@Service
public class OpenFlowControllerImpl implements OpenFlowController {
- protected ConcurrentHashMap<Long, OpenFlowSwitch> connectedSwitches;
- protected ConcurrentHashMap<Long, OpenFlowSwitch> activeMasterSwitches;
- protected ConcurrentHashMap<Long, OpenFlowSwitch> activeEqualSwitches;
+ 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 OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
- protected ArrayList<OpenFlowSwitchListener> ofEventListener;
+ protected ArrayList<OpenFlowSwitchListener> ofEventListener =
+ new ArrayList<OpenFlowSwitchListener>();
private final Controller ctrl = new Controller();
@@ -98,29 +105,17 @@
@Override
public void write(Dpid dpid, OFMessage msg) {
- this.getSwitch(dpid).write(msg);
+ this.getSwitch(dpid).sendMsg(msg);
}
@Override
public void processPacket(OFMessage msg) {
+ log.info("Got message {}", msg);
}
@Override
public void setRole(Dpid dpid, RoleState role) {
- switch (role) {
- case MASTER:
- agent.transitionToMasterSwitch(dpid.value());
- break;
- case EQUAL:
- agent.transitionToEqualSwitch(dpid.value());
- break;
- case SLAVE:
- //agent.transitionToSlaveSwitch(dpid.value());
- break;
- default:
- //WTF role is this?
- }
-
+ ((AbstractOpenFlowSwitch) getSwitch(dpid)).setRole(role);
}
public class OpenFlowSwitchAgent {
@@ -189,6 +184,7 @@
return false;
}
activeEqualSwitches.put(dpid, sw);
+ log.info("Added Activated EQUAL Switch {}", dpid);
return true;
} finally {
switchLock.unlock();
@@ -203,6 +199,9 @@
protected void transitionToMasterSwitch(long dpid) {
switchLock.lock();
try {
+ if (activeMasterSwitches.containsKey(dpid)) {
+ return;
+ }
OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
if (sw == null) {
log.error("Transition to master called on sw {}, but switch "
@@ -224,6 +223,9 @@
protected void transitionToEqualSwitch(long dpid) {
switchLock.lock();
try {
+ if (activeEqualSwitches.containsKey(dpid)) {
+ return;
+ }
OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
if (sw == null) {
log.error("Transition to equal called on sw {}, but switch "
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 f31487a..50e7b33 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
@@ -2,7 +2,6 @@
import java.io.IOException;
import java.util.Collections;
-import java.util.concurrent.atomic.AtomicInteger;
import org.onlab.onos.of.controller.RoleState;
import org.projectfloodlight.openflow.protocol.OFControllerRole;
@@ -50,7 +49,6 @@
// the expectation set by the caller for the returned role
private RoleRecvStatus expectation;
- private AtomicInteger xidCounter;
private AbstractOpenFlowSwitch sw;
@@ -58,7 +56,6 @@
this.requestPending = false;
this.pendingXid = -1;
this.pendingRole = null;
- this.xidCounter = new AtomicInteger(0);
this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE;
this.sw = sw;
}
@@ -85,7 +82,7 @@
roleToSend = OFNiciraControllerRole.ROLE_SLAVE;
log.warn("Sending Nx Role.SLAVE to switch {}.", sw);
}
- int xid = xidCounter.getAndIncrement();
+ int xid = sw.getNextTransactionId();
OFExperimenter roleRequest = OFFactories.getFactory(OFVersion.OF_10)
.buildNiciraControllerRoleRequest()
.setXid(xid)
@@ -113,7 +110,7 @@
+ " Should only be used for queries.", sw);
}
- int xid = xidCounter.getAndIncrement();
+ int xid = sw.getNextTransactionId();
OFRoleRequest rrm = OFFactories.getFactory(OFVersion.OF_13)
.buildRoleRequest()
.setRole(roleToSend)
@@ -121,7 +118,7 @@
//FIXME fix below when we actually use generation ids
.setGenerationId(U64.ZERO)
.build();
- sw.write(rrm);
+ sw.sendMsg(rrm);
return xid;
}