tom

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

...@@ -13,7 +13,7 @@ public interface OpenFlowSwitch { ...@@ -13,7 +13,7 @@ public interface OpenFlowSwitch {
13 * 13 *
14 * @param msg the message to write 14 * @param msg the message to write
15 */ 15 */
16 - public void write(OFMessage msg); 16 + public void sendMsg(OFMessage msg);
17 17
18 /** 18 /**
19 * Handle a message from the switch. 19 * Handle a message from the switch.
......
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
18 package org.onlab.onos.of.controller.impl.internal; 18 package org.onlab.onos.of.controller.impl.internal;
19 19
20 import java.io.IOException; 20 import java.io.IOException;
21 +import java.util.Collections;
21 import java.util.List; 22 import java.util.List;
23 +import java.util.concurrent.atomic.AtomicInteger;
22 24
23 import org.jboss.netty.channel.Channel; 25 import org.jboss.netty.channel.Channel;
24 import org.onlab.onos.of.controller.Dpid; 26 import org.onlab.onos.of.controller.Dpid;
...@@ -27,12 +29,14 @@ import org.onlab.onos.of.controller.RoleState; ...@@ -27,12 +29,14 @@ import org.onlab.onos.of.controller.RoleState;
27 import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent; 29 import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent;
28 import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleRecvStatus; 30 import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleRecvStatus;
29 import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleReplyInfo; 31 import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleReplyInfo;
32 +import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
30 import org.projectfloodlight.openflow.protocol.OFErrorMsg; 33 import org.projectfloodlight.openflow.protocol.OFErrorMsg;
31 import org.projectfloodlight.openflow.protocol.OFExperimenter; 34 import org.projectfloodlight.openflow.protocol.OFExperimenter;
32 import org.projectfloodlight.openflow.protocol.OFFactories; 35 import org.projectfloodlight.openflow.protocol.OFFactories;
33 import org.projectfloodlight.openflow.protocol.OFFactory; 36 import org.projectfloodlight.openflow.protocol.OFFactory;
34 import org.projectfloodlight.openflow.protocol.OFFeaturesReply; 37 import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
35 import org.projectfloodlight.openflow.protocol.OFMessage; 38 import org.projectfloodlight.openflow.protocol.OFMessage;
39 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
36 import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply; 40 import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
37 import org.projectfloodlight.openflow.protocol.OFRoleReply; 41 import org.projectfloodlight.openflow.protocol.OFRoleReply;
38 import org.projectfloodlight.openflow.protocol.OFVersion; 42 import org.projectfloodlight.openflow.protocol.OFVersion;
...@@ -45,10 +49,13 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -45,10 +49,13 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
45 private static Logger log = 49 private static Logger log =
46 LoggerFactory.getLogger(AbstractOpenFlowSwitch.class); 50 LoggerFactory.getLogger(AbstractOpenFlowSwitch.class);
47 51
48 - private Channel channel; 52 + protected Channel channel;
53 + protected boolean startDriverHandshakeCalled = false;
54 +
49 private boolean connected; 55 private boolean connected;
50 private Dpid dpid; 56 private Dpid dpid;
51 private OpenFlowSwitchAgent agent; 57 private OpenFlowSwitchAgent agent;
58 + private AtomicInteger xidCounter = new AtomicInteger(0);
52 59
53 private OFVersion ofVersion; 60 private OFVersion ofVersion;
54 61
...@@ -58,8 +65,12 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -58,8 +65,12 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
58 65
59 private final RoleManager roleMan = new RoleManager(this); 66 private final RoleManager roleMan = new RoleManager(this);
60 67
61 - protected AbstractOpenFlowSwitch(long dpid) { 68 + protected RoleState role;
62 - this.dpid = new Dpid(dpid); 69 +
70 + protected OFFeaturesReply features;
71 +
72 + protected AbstractOpenFlowSwitch(Dpid dp) {
73 + this.dpid = dp;
63 } 74 }
64 75
65 //************************ 76 //************************
...@@ -80,14 +91,16 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -80,14 +91,16 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
80 * 91 *
81 * @param m the message to be written 92 * @param m the message to be written
82 */ 93 */
83 - public abstract void write(OFMessage m); 94 + public abstract void sendMsg(OFMessage m);
84 95
85 /** 96 /**
86 * Writes to the OFMessage list to the output stream. 97 * Writes to the OFMessage list to the output stream.
87 * 98 *
88 * @param msgs the messages to be written 99 * @param msgs the messages to be written
89 */ 100 */
90 - public abstract void write(List<OFMessage> msgs); 101 + public void write(List<OFMessage> msgs) {
102 + this.channel.write(msgs);
103 + }
91 104
92 105
93 /** 106 /**
...@@ -151,7 +164,9 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -151,7 +164,9 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
151 this.tableFull = full; 164 this.tableFull = full;
152 } 165 }
153 166
154 - public abstract void setFeaturesReply(OFFeaturesReply featuresReply); 167 + public void setFeaturesReply(OFFeaturesReply featuresReply) {
168 + this.features = featuresReply;
169 + }
155 170
156 /** 171 /**
157 * Let peoeple know if you support Nicira style role requests. 172 * Let peoeple know if you support Nicira style role requests.
...@@ -172,7 +187,9 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -172,7 +187,9 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
172 this.agent.processMessage(m); 187 this.agent.processMessage(m);
173 } 188 }
174 189
175 - public abstract RoleState getRole(); 190 + public RoleState getRole() {
191 + return role;
192 + };
176 193
177 final boolean addConnectedSwitch() { 194 final boolean addConnectedSwitch() {
178 return this.agent.addConnectedSwitch(this.getId(), this); 195 return this.agent.addConnectedSwitch(this.getId(), this);
...@@ -214,7 +231,9 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -214,7 +231,9 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
214 231
215 public void setRole(RoleState role) { 232 public void setRole(RoleState role) {
216 try { 233 try {
217 - this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE); 234 + if (this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE)) {
235 + this.role = role;
236 + }
218 } catch (IOException e) { 237 } catch (IOException e) {
219 log.error("Unable to write to switch {}.", this.dpid); 238 log.error("Unable to write to switch {}.", this.dpid);
220 } 239 }
...@@ -236,23 +255,23 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -236,23 +255,23 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
236 } 255 }
237 256
238 void handleNiciraRole(OFMessage m) throws SwitchStateException { 257 void handleNiciraRole(OFMessage m) throws SwitchStateException {
239 - RoleState role = this.roleMan.extractNiciraRoleReply((OFExperimenter) m); 258 + RoleState r = this.roleMan.extractNiciraRoleReply((OFExperimenter) m);
240 - if (role == null) { 259 + if (r == null) {
241 - // The message wasn't really a Nicira role reply. We just 260 + // The message wasn't really a Nicira role reply. We just
242 - // dispatch it to the OFMessage listeners in this case. 261 + // dispatch it to the OFMessage listeners in this case.
243 - this.handleMessage(m); 262 + this.handleMessage(m);
244 - } 263 + }
245 - 264 +
246 - RoleRecvStatus rrs = this.roleMan.deliverRoleReply( 265 + RoleRecvStatus rrs = this.roleMan.deliverRoleReply(
247 - new RoleReplyInfo(role, null, m.getXid())); 266 + new RoleReplyInfo(r, null, m.getXid()));
248 - if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) { 267 + if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
249 - if (role == RoleState.MASTER) { 268 + if (r == RoleState.MASTER) {
250 - this.transitionToMasterSwitch(); 269 + this.transitionToMasterSwitch();
251 - } else if (role == RoleState.EQUAL || 270 + } else if (r == RoleState.EQUAL ||
252 - role == RoleState.SLAVE) { 271 + r == RoleState.SLAVE) {
253 - this.transitionToEqualSwitch(); 272 + this.transitionToEqualSwitch();
254 - } 273 + }
255 - } 274 + }
256 } 275 }
257 276
258 boolean handleRoleError(OFErrorMsg error) { 277 boolean handleRoleError(OFErrorMsg error) {
...@@ -274,6 +293,16 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -274,6 +293,16 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
274 this.agent = ag; 293 this.agent = ag;
275 } 294 }
276 295
296 + public void setSwitchDescription(OFDescStatsReply desc) {
297 + // TODO Auto-generated method stub
298 + }
299 +
300 + protected int getNextTransactionId() {
301 + return this.xidCounter.getAndIncrement();
302 + }
277 303
304 + protected List<OFPortDesc> getPorts() {
305 + return Collections.unmodifiableList(ports.getEntries());
306 + }
278 307
279 } 308 }
......
...@@ -29,9 +29,11 @@ import org.jboss.netty.channel.ChannelPipelineFactory; ...@@ -29,9 +29,11 @@ import org.jboss.netty.channel.ChannelPipelineFactory;
29 import org.jboss.netty.channel.group.ChannelGroup; 29 import org.jboss.netty.channel.group.ChannelGroup;
30 import org.jboss.netty.channel.group.DefaultChannelGroup; 30 import org.jboss.netty.channel.group.DefaultChannelGroup;
31 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; 31 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
32 +import org.onlab.onos.of.controller.Dpid;
32 import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc; 33 import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
33 import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs; 34 import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
34 import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent; 35 import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent;
36 +import org.onlab.onos.of.drivers.DriverManager;
35 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 37 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
36 import org.projectfloodlight.openflow.protocol.OFFactories; 38 import org.projectfloodlight.openflow.protocol.OFFactories;
37 import org.projectfloodlight.openflow.protocol.OFFactory; 39 import org.projectfloodlight.openflow.protocol.OFFactory;
...@@ -83,11 +85,6 @@ public class Controller { ...@@ -83,11 +85,6 @@ public class Controller {
83 // Getters/Setters 85 // Getters/Setters
84 // *************** 86 // ***************
85 87
86 -
87 - public synchronized void setIOFSwitchManager(IOFSwitchManager swManager) {
88 - this.switchManager = swManager;
89 - }
90 -
91 public OFFactory getOFMessageFactory10() { 88 public OFFactory getOFMessageFactory10() {
92 return FACTORY10; 89 return FACTORY10;
93 } 90 }
...@@ -201,18 +198,6 @@ public class Controller { ...@@ -201,18 +198,6 @@ public class Controller {
201 198
202 } 199 }
203 200
204 - /**
205 - * Startup all of the controller's components.
206 - */
207 - @LogMessageDoc(message = "Waiting for storage source",
208 - explanation = "The system database is not yet ready",
209 - recommendation = "If this message persists, this indicates " +
210 - "that the system database has failed to start. " +
211 - LogMessageDoc.CHECK_CONTROLLER)
212 - public synchronized void startupComponents() {
213 - //TODO do something maybe
214 - }
215 -
216 // ************** 201 // **************
217 // Utility methods 202 // Utility methods
218 // ************** 203 // **************
...@@ -236,9 +221,10 @@ public class Controller { ...@@ -236,9 +221,10 @@ public class Controller {
236 * @param desc 221 * @param desc
237 * @return switch instance 222 * @return switch instance
238 */ 223 */
239 - protected AbstractOpenFlowSwitch getOFSwitchInstance(OFDescStatsReply desc, OFVersion ofv) { 224 + protected AbstractOpenFlowSwitch getOFSwitchInstance(long dpid,
240 - AbstractOpenFlowSwitch sw = switchManager.getSwitchImpl(desc.getMfrDesc(), desc.getHwDesc(), 225 + OFDescStatsReply desc, OFVersion ofv) {
241 - desc.getSwDesc(), ofv); 226 + AbstractOpenFlowSwitch sw = DriverManager.getOFSwitchImpl(new Dpid(dpid),
227 + desc, ofv);
242 sw.setAgent(agent); 228 sw.setAgent(agent);
243 return sw; 229 return sw;
244 } 230 }
...@@ -247,7 +233,6 @@ public class Controller { ...@@ -247,7 +233,6 @@ public class Controller {
247 log.info("Initialising OpenFlow Lib and IO"); 233 log.info("Initialising OpenFlow Lib and IO");
248 this.agent = ag; 234 this.agent = ag;
249 this.init(new HashMap<String, String>()); 235 this.init(new HashMap<String, String>());
250 - this.startupComponents();
251 this.run(); 236 this.run();
252 } 237 }
253 238
......
...@@ -65,7 +65,6 @@ import org.slf4j.LoggerFactory; ...@@ -65,7 +65,6 @@ import org.slf4j.LoggerFactory;
65 */ 65 */
66 class OFChannelHandler extends IdleStateAwareChannelHandler { 66 class OFChannelHandler extends IdleStateAwareChannelHandler {
67 private static final Logger log = LoggerFactory.getLogger(OFChannelHandler.class); 67 private static final Logger log = LoggerFactory.getLogger(OFChannelHandler.class);
68 - private static final long DEFAULT_ROLE_TIMEOUT_MS = 2 * 1000; // 10 sec
69 private final Controller controller; 68 private final Controller controller;
70 private AbstractOpenFlowSwitch sw; 69 private AbstractOpenFlowSwitch sw;
71 private long thisdpid; // channelHandler cached value of connected switch id 70 private long thisdpid; // channelHandler cached value of connected switch id
...@@ -230,12 +229,6 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -230,12 +229,6 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
230 h.thisdpid = m.getDatapathId().getLong(); 229 h.thisdpid = m.getDatapathId().getLong();
231 log.info("Received features reply for switch at {} with dpid {}", 230 log.info("Received features reply for switch at {} with dpid {}",
232 h.getSwitchInfoString(), h.thisdpid); 231 h.getSwitchInfoString(), h.thisdpid);
233 - //update the controller about this connected switch
234 - boolean success = h.sw.addConnectedSwitch();
235 - if (!success) {
236 - disconnectDuplicate(h);
237 - return;
238 - }
239 232
240 h.featuresReply = m; //temp store 233 h.featuresReply = m; //temp store
241 if (h.ofVersion == OFVersion.OF_10) { 234 if (h.ofVersion == OFVersion.OF_10) {
...@@ -419,7 +412,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -419,7 +412,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
419 h.channel.getRemoteAddress()); 412 h.channel.getRemoteAddress());
420 OFDescStatsReply drep = (OFDescStatsReply) m; 413 OFDescStatsReply drep = (OFDescStatsReply) m;
421 // Here is where we differentiate between different kinds of switches 414 // Here is where we differentiate between different kinds of switches
422 - h.sw = h.controller.getOFSwitchInstance(drep, h.ofVersion); 415 + h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion);
416 + boolean success = h.sw.addConnectedSwitch();
417 + if (!success) {
418 + disconnectDuplicate(h);
419 + return;
420 + }
423 // set switch information 421 // set switch information
424 h.sw.setOFVersion(h.ofVersion); 422 h.sw.setOFVersion(h.ofVersion);
425 h.sw.setFeaturesReply(h.featuresReply); 423 h.sw.setFeaturesReply(h.featuresReply);
...@@ -433,7 +431,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -433,7 +431,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
433 //Put switch in EQUAL mode until we hear back from the global registry 431 //Put switch in EQUAL mode until we hear back from the global registry
434 log.debug("Setting new switch {} to EQUAL and sending Role request", 432 log.debug("Setting new switch {} to EQUAL and sending Role request",
435 h.sw.getStringId()); 433 h.sw.getStringId());
436 - h.setSwitchRole(RoleState.EQUAL); 434 + h.sw.addActivatedEqualSwitch();
435 + //h.setSwitchRole(RoleState.EQUAL);
436 + h.setSwitchRole(RoleState.MASTER);
437 h.sw.startDriverHandshake(); 437 h.sw.startDriverHandshake();
438 h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE); 438 h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
439 439
......
...@@ -24,12 +24,19 @@ import org.slf4j.LoggerFactory; ...@@ -24,12 +24,19 @@ import org.slf4j.LoggerFactory;
24 @Service 24 @Service
25 public class OpenFlowControllerImpl implements OpenFlowController { 25 public class OpenFlowControllerImpl implements OpenFlowController {
26 26
27 - protected ConcurrentHashMap<Long, OpenFlowSwitch> connectedSwitches; 27 + private static final Logger log =
28 - protected ConcurrentHashMap<Long, OpenFlowSwitch> activeMasterSwitches; 28 + LoggerFactory.getLogger(OpenFlowControllerImpl.class);
29 - protected ConcurrentHashMap<Long, OpenFlowSwitch> activeEqualSwitches; 29 +
30 + protected ConcurrentHashMap<Long, OpenFlowSwitch> connectedSwitches =
31 + new ConcurrentHashMap<Long, OpenFlowSwitch>();
32 + protected ConcurrentHashMap<Long, OpenFlowSwitch> activeMasterSwitches =
33 + new ConcurrentHashMap<Long, OpenFlowSwitch>();
34 + protected ConcurrentHashMap<Long, OpenFlowSwitch> activeEqualSwitches =
35 + new ConcurrentHashMap<Long, OpenFlowSwitch>();
30 36
31 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent(); 37 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
32 - protected ArrayList<OpenFlowSwitchListener> ofEventListener; 38 + protected ArrayList<OpenFlowSwitchListener> ofEventListener =
39 + new ArrayList<OpenFlowSwitchListener>();
33 40
34 private final Controller ctrl = new Controller(); 41 private final Controller ctrl = new Controller();
35 42
...@@ -98,29 +105,17 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -98,29 +105,17 @@ public class OpenFlowControllerImpl implements OpenFlowController {
98 105
99 @Override 106 @Override
100 public void write(Dpid dpid, OFMessage msg) { 107 public void write(Dpid dpid, OFMessage msg) {
101 - this.getSwitch(dpid).write(msg); 108 + this.getSwitch(dpid).sendMsg(msg);
102 } 109 }
103 110
104 @Override 111 @Override
105 public void processPacket(OFMessage msg) { 112 public void processPacket(OFMessage msg) {
113 + log.info("Got message {}", msg);
106 } 114 }
107 115
108 @Override 116 @Override
109 public void setRole(Dpid dpid, RoleState role) { 117 public void setRole(Dpid dpid, RoleState role) {
110 - switch (role) { 118 + ((AbstractOpenFlowSwitch) getSwitch(dpid)).setRole(role);
111 - case MASTER:
112 - agent.transitionToMasterSwitch(dpid.value());
113 - break;
114 - case EQUAL:
115 - agent.transitionToEqualSwitch(dpid.value());
116 - break;
117 - case SLAVE:
118 - //agent.transitionToSlaveSwitch(dpid.value());
119 - break;
120 - default:
121 - //WTF role is this?
122 - }
123 -
124 } 119 }
125 120
126 public class OpenFlowSwitchAgent { 121 public class OpenFlowSwitchAgent {
...@@ -189,6 +184,7 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -189,6 +184,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
189 return false; 184 return false;
190 } 185 }
191 activeEqualSwitches.put(dpid, sw); 186 activeEqualSwitches.put(dpid, sw);
187 + log.info("Added Activated EQUAL Switch {}", dpid);
192 return true; 188 return true;
193 } finally { 189 } finally {
194 switchLock.unlock(); 190 switchLock.unlock();
...@@ -203,6 +199,9 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -203,6 +199,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
203 protected void transitionToMasterSwitch(long dpid) { 199 protected void transitionToMasterSwitch(long dpid) {
204 switchLock.lock(); 200 switchLock.lock();
205 try { 201 try {
202 + if (activeMasterSwitches.containsKey(dpid)) {
203 + return;
204 + }
206 OpenFlowSwitch sw = activeEqualSwitches.remove(dpid); 205 OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
207 if (sw == null) { 206 if (sw == null) {
208 log.error("Transition to master called on sw {}, but switch " 207 log.error("Transition to master called on sw {}, but switch "
...@@ -224,6 +223,9 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -224,6 +223,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
224 protected void transitionToEqualSwitch(long dpid) { 223 protected void transitionToEqualSwitch(long dpid) {
225 switchLock.lock(); 224 switchLock.lock();
226 try { 225 try {
226 + if (activeEqualSwitches.containsKey(dpid)) {
227 + return;
228 + }
227 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid); 229 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
228 if (sw == null) { 230 if (sw == null) {
229 log.error("Transition to equal called on sw {}, but switch " 231 log.error("Transition to equal called on sw {}, but switch "
......
...@@ -2,7 +2,6 @@ package org.onlab.onos.of.controller.impl.internal; ...@@ -2,7 +2,6 @@ package org.onlab.onos.of.controller.impl.internal;
2 2
3 import java.io.IOException; 3 import java.io.IOException;
4 import java.util.Collections; 4 import java.util.Collections;
5 -import java.util.concurrent.atomic.AtomicInteger;
6 5
7 import org.onlab.onos.of.controller.RoleState; 6 import org.onlab.onos.of.controller.RoleState;
8 import org.projectfloodlight.openflow.protocol.OFControllerRole; 7 import org.projectfloodlight.openflow.protocol.OFControllerRole;
...@@ -50,7 +49,6 @@ class RoleManager { ...@@ -50,7 +49,6 @@ class RoleManager {
50 49
51 // the expectation set by the caller for the returned role 50 // the expectation set by the caller for the returned role
52 private RoleRecvStatus expectation; 51 private RoleRecvStatus expectation;
53 - private AtomicInteger xidCounter;
54 private AbstractOpenFlowSwitch sw; 52 private AbstractOpenFlowSwitch sw;
55 53
56 54
...@@ -58,7 +56,6 @@ class RoleManager { ...@@ -58,7 +56,6 @@ class RoleManager {
58 this.requestPending = false; 56 this.requestPending = false;
59 this.pendingXid = -1; 57 this.pendingXid = -1;
60 this.pendingRole = null; 58 this.pendingRole = null;
61 - this.xidCounter = new AtomicInteger(0);
62 this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE; 59 this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE;
63 this.sw = sw; 60 this.sw = sw;
64 } 61 }
...@@ -85,7 +82,7 @@ class RoleManager { ...@@ -85,7 +82,7 @@ class RoleManager {
85 roleToSend = OFNiciraControllerRole.ROLE_SLAVE; 82 roleToSend = OFNiciraControllerRole.ROLE_SLAVE;
86 log.warn("Sending Nx Role.SLAVE to switch {}.", sw); 83 log.warn("Sending Nx Role.SLAVE to switch {}.", sw);
87 } 84 }
88 - int xid = xidCounter.getAndIncrement(); 85 + int xid = sw.getNextTransactionId();
89 OFExperimenter roleRequest = OFFactories.getFactory(OFVersion.OF_10) 86 OFExperimenter roleRequest = OFFactories.getFactory(OFVersion.OF_10)
90 .buildNiciraControllerRoleRequest() 87 .buildNiciraControllerRoleRequest()
91 .setXid(xid) 88 .setXid(xid)
...@@ -113,7 +110,7 @@ class RoleManager { ...@@ -113,7 +110,7 @@ class RoleManager {
113 + " Should only be used for queries.", sw); 110 + " Should only be used for queries.", sw);
114 } 111 }
115 112
116 - int xid = xidCounter.getAndIncrement(); 113 + int xid = sw.getNextTransactionId();
117 OFRoleRequest rrm = OFFactories.getFactory(OFVersion.OF_13) 114 OFRoleRequest rrm = OFFactories.getFactory(OFVersion.OF_13)
118 .buildRoleRequest() 115 .buildRoleRequest()
119 .setRole(roleToSend) 116 .setRole(roleToSend)
...@@ -121,7 +118,7 @@ class RoleManager { ...@@ -121,7 +118,7 @@ class RoleManager {
121 //FIXME fix below when we actually use generation ids 118 //FIXME fix below when we actually use generation ids
122 .setGenerationId(U64.ZERO) 119 .setGenerationId(U64.ZERO)
123 .build(); 120 .build();
124 - sw.write(rrm); 121 + sw.sendMsg(rrm);
125 return xid; 122 return xid;
126 } 123 }
127 124
......
1 +package org.onlab.onos.of.drivers;
2 +
3 +
4 +
5 +import org.onlab.onos.of.controller.Dpid;
6 +import org.onlab.onos.of.controller.RoleState;
7 +import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch;
8 +import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
9 +import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
10 +import org.projectfloodlight.openflow.protocol.OFMessage;
11 +import org.projectfloodlight.openflow.protocol.OFVersion;
12 +import org.slf4j.Logger;
13 +import org.slf4j.LoggerFactory;
14 +
15 +/**
16 + * A simple implementation of a driver manager that differentiates between
17 + * connected switches using the OF Description Statistics Reply message.
18 + */
19 +public final class DriverManager {
20 +
21 + private static final Logger log = LoggerFactory.getLogger(DriverManager.class);
22 +
23 + // Whether to use an OF 1.3 configured TTP, or to use an OF 1.0-style
24 + // single table with packet-ins.
25 + private static boolean cpqdUsePipeline13 = false;
26 +
27 + /**
28 + * Return an IOFSwitch object based on switch's manufacturer description
29 + * from OFDescStatsReply.
30 + *
31 + * @param desc DescriptionStatistics reply from the switch
32 + * @return A IOFSwitch instance if the driver found an implementation for
33 + * the given description. Otherwise it returns OFSwitchImplBase
34 + */
35 + public static AbstractOpenFlowSwitch getOFSwitchImpl(Dpid dpid,
36 + OFDescStatsReply desc, OFVersion ofv) {
37 + String vendor = desc.getMfrDesc();
38 + String hw = desc.getHwDesc();
39 + if (vendor.startsWith("Stanford University, Ericsson Research and CPqD Research")
40 + &&
41 + hw.startsWith("OpenFlow 1.3 Reference Userspace Switch")) {
42 + return new OFSwitchImplCPqD13(dpid, desc, cpqdUsePipeline13);
43 + }
44 +
45 + if (vendor.startsWith("Nicira") &&
46 + hw.startsWith("Open vSwitch")) {
47 + if (ofv == OFVersion.OF_10) {
48 + return new OFSwitchImplOVS10(dpid, desc);
49 + } else if (ofv == OFVersion.OF_13) {
50 + return new OFSwitchImplOVS13(dpid, desc);
51 + }
52 + }
53 +
54 + log.warn("DriverManager could not identify switch desc: {}. "
55 + + "Assigning OFSwitchImplBase", desc);
56 + AbstractOpenFlowSwitch base = new AbstractOpenFlowSwitch(dpid) {
57 +
58 +
59 + @Override
60 + public void sendMsg(OFMessage m) {
61 + channel.write(m);
62 + }
63 +
64 + @Override
65 + public Boolean supportNxRole() {
66 + return false;
67 + }
68 +
69 + @Override
70 + public void startDriverHandshake() {}
71 +
72 + @Override
73 + public void setFeaturesReply(OFFeaturesReply featuresReply) {
74 + this.features = featuresReply;
75 + }
76 +
77 + @Override
78 + public void processDriverHandshakeMessage(OFMessage m) {}
79 +
80 + @Override
81 + public boolean isDriverHandshakeComplete() {
82 + return true;
83 + }
84 +
85 + @Override
86 + public RoleState getRole() {
87 + return role;
88 + }
89 + };
90 + base.setSwitchDescription(desc);
91 + return base;
92 + }
93 +
94 + /**
95 + * Private constructor to avoid instantiation.
96 + */
97 + private DriverManager() {
98 + }
99 +
100 + /**
101 + * Sets the configuration parameter which determines how the CPqD switch
102 + * is set up. If usePipeline13 is true, a 1.3 pipeline will be set up on
103 + * the switch. Otherwise, the switch will be set up in a 1.0 style with
104 + * a single table where missed packets are sent to the controller.
105 + *
106 + * @param usePipeline13 whether to use a 1.3 pipeline or not
107 + */
108 + public static void setConfigForCpqd(boolean usePipeline13) {
109 + cpqdUsePipeline13 = usePipeline13;
110 + }
111 +}
1 +package org.onlab.onos.of.drivers;
2 +
3 +import org.onlab.onos.of.controller.Dpid;
4 +import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch;
5 +import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
6 +import org.projectfloodlight.openflow.protocol.OFMessage;
7 +
8 +/**
9 + * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
10 + * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
11 + * 1.11.90 (or whatever version + build) Serial : None
12 + */
13 +public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
14 +
15 + public OFSwitchImplOVS10(Dpid dpid, OFDescStatsReply desc) {
16 + super(dpid);
17 + setSwitchDescription(desc);
18 +
19 + }
20 +
21 + /* (non-Javadoc)
22 + * @see java.lang.Object#toString()
23 + */
24 + @Override
25 + public String toString() {
26 + return "OFSwitchImplOVS10 [" + ((channel != null)
27 + ? channel.getRemoteAddress() : "?")
28 + + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
29 + }
30 +
31 + @Override
32 + public void sendMsg(OFMessage m) {
33 + channel.write(m);
34 + }
35 +
36 + @Override
37 + public Boolean supportNxRole() {
38 + return true;
39 + }
40 +
41 + @Override
42 + public void startDriverHandshake() {}
43 +
44 + @Override
45 + public boolean isDriverHandshakeComplete() {
46 + return true;
47 + }
48 +
49 + @Override
50 + public void processDriverHandshakeMessage(OFMessage m) {}
51 +}
1 +package org.onlab.onos.of.drivers;
2 +
3 +import java.util.concurrent.atomic.AtomicBoolean;
4 +
5 +import org.onlab.onos.of.controller.Dpid;
6 +import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch;
7 +import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeAlreadyStarted;
8 +import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeCompleted;
9 +import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeNotStarted;
10 +import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
11 +import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
12 +import org.projectfloodlight.openflow.protocol.OFErrorMsg;
13 +import org.projectfloodlight.openflow.protocol.OFFactory;
14 +import org.projectfloodlight.openflow.protocol.OFMessage;
15 +import org.slf4j.Logger;
16 +import org.slf4j.LoggerFactory;
17 +
18 +/**
19 + * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
20 + * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
21 + * 2.1.0 (or whatever version + build) Serial : None
22 + */
23 +public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
24 +
25 + private static Logger log =
26 + LoggerFactory.getLogger(OFSwitchImplOVS13.class);
27 +
28 + private AtomicBoolean driverHandshakeComplete;
29 + private OFFactory factory;
30 + private long barrierXidToWaitFor = -1;
31 +
32 + public OFSwitchImplOVS13(Dpid dpid, OFDescStatsReply desc) {
33 + super(dpid);
34 + driverHandshakeComplete = new AtomicBoolean(false);
35 + setSwitchDescription(desc);
36 + }
37 +
38 + @Override
39 + public String toString() {
40 + return "OFSwitchImplOVS13 [" + ((channel != null)
41 + ? channel.getRemoteAddress() : "?")
42 + + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
43 + }
44 +
45 + @Override
46 + public void startDriverHandshake() {
47 + log.debug("Starting driver handshake for sw {}", getStringId());
48 + if (startDriverHandshakeCalled) {
49 + throw new SwitchDriverSubHandshakeAlreadyStarted();
50 + }
51 + startDriverHandshakeCalled = true;
52 + factory = factory();
53 + configureSwitch();
54 + }
55 +
56 + @Override
57 + public boolean isDriverHandshakeComplete() {
58 + if (!startDriverHandshakeCalled) {
59 + throw new SwitchDriverSubHandshakeNotStarted();
60 + }
61 + return driverHandshakeComplete.get();
62 + }
63 +
64 + @Override
65 + public void processDriverHandshakeMessage(OFMessage m) {
66 + if (!startDriverHandshakeCalled) {
67 + throw new SwitchDriverSubHandshakeNotStarted();
68 + }
69 + if (driverHandshakeComplete.get()) {
70 + throw new SwitchDriverSubHandshakeCompleted(m);
71 + }
72 +
73 + switch (m.getType()) {
74 + case BARRIER_REPLY:
75 + if (m.getXid() == barrierXidToWaitFor) {
76 + driverHandshakeComplete.set(true);
77 + }
78 + break;
79 +
80 + case ERROR:
81 + log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m);
82 + break;
83 +
84 + case FEATURES_REPLY:
85 + break;
86 + case FLOW_REMOVED:
87 + break;
88 + case GET_ASYNC_REPLY:
89 + // OFAsyncGetReply asrep = (OFAsyncGetReply)m;
90 + // decodeAsyncGetReply(asrep);
91 + break;
92 +
93 + case PACKET_IN:
94 + break;
95 + case PORT_STATUS:
96 + break;
97 + case QUEUE_GET_CONFIG_REPLY:
98 + break;
99 + case ROLE_REPLY:
100 + break;
101 +
102 + case STATS_REPLY:
103 + // processStatsReply((OFStatsReply) m);
104 + break;
105 +
106 + default:
107 + log.debug("Received message {} during switch-driver subhandshake "
108 + + "from switch {} ... Ignoring message", m, getStringId());
109 +
110 + }
111 + }
112 +
113 +
114 + private void configureSwitch() {
115 + sendBarrier(true);
116 + }
117 +
118 +
119 + private void sendBarrier(boolean finalBarrier) {
120 + int xid = getNextTransactionId();
121 + if (finalBarrier) {
122 + barrierXidToWaitFor = xid;
123 + }
124 + OFBarrierRequest br = factory
125 + .buildBarrierRequest()
126 + .setXid(xid)
127 + .build();
128 + sendMsg(br);
129 + }
130 +
131 + @Override
132 + public void sendMsg(OFMessage m) {
133 + channel.write(m);
134 + }
135 +
136 + @Override
137 + public Boolean supportNxRole() {
138 + return false;
139 + }
140 +}