Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
Showing
10 changed files
with
396 additions
and
81 deletions
... | @@ -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 | +} |
This diff is collapsed. Click to expand it.
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 | +} |
-
Please register or login to post a comment