alshabib

refactored OF switch into driver and frontend

Showing 24 changed files with 788 additions and 378 deletions
1 package org.onlab.onos.of.controller; 1 package org.onlab.onos.of.controller;
2 2
3 +import java.util.List;
4 +
5 +import org.projectfloodlight.openflow.protocol.OFFactory;
3 import org.projectfloodlight.openflow.protocol.OFMessage; 6 import org.projectfloodlight.openflow.protocol.OFMessage;
7 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
4 8
5 /** 9 /**
6 - * Abstract model of an OpenFlow Switch. 10 + * Represents to provider facing side of a switch.
7 - *
8 */ 11 */
9 public interface OpenFlowSwitch { 12 public interface OpenFlowSwitch {
10 13
11 /** 14 /**
12 - * Writes the message to this switch. 15 + * Writes the message to the driver.
13 * 16 *
14 * @param msg the message to write 17 * @param msg the message to write
15 */ 18 */
16 public void sendMsg(OFMessage msg); 19 public void sendMsg(OFMessage msg);
17 20
18 /** 21 /**
22 + * Writes to the OFMessage list to the driver.
23 + *
24 + * @param msgs the messages to be written
25 + */
26 + public void sendMsg(List<OFMessage> msgs);
27 +
28 + /**
19 * Handle a message from the switch. 29 * Handle a message from the switch.
20 * @param fromSwitch the message to handle 30 * @param fromSwitch the message to handle
21 */ 31 */
22 public void handleMessage(OFMessage fromSwitch); 32 public void handleMessage(OFMessage fromSwitch);
33 +
34 + /**
35 + * Sets the role for this switch.
36 + * @param role the role to set.
37 + */
38 + public void setRole(RoleState role);
39 +
40 + /**
41 + * Fetch the role for this switch.
42 + * @return the role.
43 + */
44 + public RoleState getRole();
45 +
46 + /**
47 + * Fetches the ports of this switch.
48 + * @return unmodifiable list of the ports.
49 + */
50 + public List<OFPortDesc> getPorts();
51 +
52 + /**
53 + * Provides the factory for this OF version.
54 + * @return OF version specific factory.
55 + */
56 + public OFFactory factory();
57 +
58 + /**
59 + * Gets a string version of the ID for this switch.
60 + *
61 + * @return string version of the ID
62 + */
63 + public String getStringId();
64 +
65 + /**
66 + * Gets the datapathId of the switch.
67 + *
68 + * @return the switch dpid in long format
69 + */
70 + public long getId();
71 +
72 + /**
73 + * Disconnects the switch by closing the TCP connection. Results in a call
74 + * to the channel handler's channelDisconnected method for cleanup
75 + */
76 + public void disconnectSwitch();
77 +
23 } 78 }
......
...@@ -21,3 +21,5 @@ public enum RoleState { ...@@ -21,3 +21,5 @@ public enum RoleState {
21 21
22 } 22 }
23 23
24 +
25 +
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
15 * under the License. 15 * under the License.
16 **/ 16 **/
17 17
18 -package org.onlab.onos.of.controller.impl.internal; 18 +package org.onlab.onos.of.controller.driver;
19 19
20 import java.io.IOException; 20 import java.io.IOException;
21 import java.util.Collections; 21 import java.util.Collections;
...@@ -24,11 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -24,11 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger;
24 24
25 import org.jboss.netty.channel.Channel; 25 import org.jboss.netty.channel.Channel;
26 import org.onlab.onos.of.controller.Dpid; 26 import org.onlab.onos.of.controller.Dpid;
27 -import org.onlab.onos.of.controller.OpenFlowSwitch;
28 import org.onlab.onos.of.controller.RoleState; 27 import org.onlab.onos.of.controller.RoleState;
29 -import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent;
30 -import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleRecvStatus;
31 -import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleReplyInfo;
32 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 28 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
33 import org.projectfloodlight.openflow.protocol.OFErrorMsg; 29 import org.projectfloodlight.openflow.protocol.OFErrorMsg;
34 import org.projectfloodlight.openflow.protocol.OFExperimenter; 30 import org.projectfloodlight.openflow.protocol.OFExperimenter;
...@@ -43,19 +39,22 @@ import org.projectfloodlight.openflow.protocol.OFVersion; ...@@ -43,19 +39,22 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
43 import org.slf4j.Logger; 39 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory; 40 import org.slf4j.LoggerFactory;
45 41
46 - 42 +/**
47 -public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { 43 + * An abstract representation of an OpenFlow switch. Can be extended by others
44 + * to serve as a base for their vendor specific representation of a switch.
45 + */
46 +public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
48 47
49 private static Logger log = 48 private static Logger log =
50 LoggerFactory.getLogger(AbstractOpenFlowSwitch.class); 49 LoggerFactory.getLogger(AbstractOpenFlowSwitch.class);
51 50
52 protected Channel channel; 51 protected Channel channel;
53 - protected boolean startDriverHandshakeCalled = false;
54 52
55 private boolean connected; 53 private boolean connected;
56 - private Dpid dpid; 54 + protected boolean startDriverHandshakeCalled = false;
57 - private OpenFlowSwitchAgent agent; 55 + private final Dpid dpid;
58 - private AtomicInteger xidCounter = new AtomicInteger(0); 56 + private OpenFlowAgent agent;
57 + private final AtomicInteger xidCounter = new AtomicInteger(0);
59 58
60 private OFVersion ofVersion; 59 private OFVersion ofVersion;
61 60
...@@ -63,12 +62,17 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -63,12 +62,17 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
63 62
64 protected boolean tableFull; 63 protected boolean tableFull;
65 64
66 - private final RoleManager roleMan = new RoleManager(this); 65 + private RoleHandler roleMan;
67 66
68 protected RoleState role; 67 protected RoleState role;
69 68
70 protected OFFeaturesReply features; 69 protected OFFeaturesReply features;
70 + protected OFDescStatsReply desc;
71 71
72 + /**
73 + * Given a dpid build this switch.
74 + * @param dp the dpid
75 + */
72 protected AbstractOpenFlowSwitch(Dpid dp) { 76 protected AbstractOpenFlowSwitch(Dpid dp) {
73 this.dpid = dp; 77 this.dpid = dp;
74 } 78 }
...@@ -77,59 +81,38 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -77,59 +81,38 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
77 // Channel related 81 // Channel related
78 //************************ 82 //************************
79 83
80 - /** 84 + @Override
81 - * Disconnects the switch by closing the TCP connection. Results in a call
82 - * to the channel handler's channelDisconnected method for cleanup
83 - * @throws IOException
84 - */
85 public final void disconnectSwitch() { 85 public final void disconnectSwitch() {
86 this.channel.close(); 86 this.channel.close();
87 } 87 }
88 88
89 - /** 89 + @Override
90 - * Writes to the OFMessage to the output stream. 90 + public final void sendMsg(OFMessage m) {
91 - * 91 + this.write(m);
92 - * @param m the message to be written 92 + }
93 - */
94 - public abstract void sendMsg(OFMessage m);
95 93
96 - /** 94 + @Override
97 - * Writes to the OFMessage list to the output stream. 95 + public final void sendMsg(List<OFMessage> msgs) {
98 - * 96 + this.write(msgs);
99 - * @param msgs the messages to be written
100 - */
101 - public void write(List<OFMessage> msgs) {
102 - this.channel.write(msgs);
103 } 97 }
104 98
99 + @Override
100 + public abstract void write(OFMessage msg);
105 101
106 - /** 102 + @Override
107 - * Checks if the switch is still connected. 103 + public abstract void write(List<OFMessage> msgs);
108 - * Only call while holding processMessageLock 104 +
109 - * 105 + @Override
110 - * @return whether the switch is still disconnected
111 - */
112 public final boolean isConnected() { 106 public final boolean isConnected() {
113 return this.connected; 107 return this.connected;
114 } 108 }
115 109
116 - /** 110 + @Override
117 - * Sets whether the switch is connected. 111 + public final void setConnected(boolean connected) {
118 - * Only call while holding modifySwitchLock
119 - *
120 - * @param connected whether the switch is connected
121 - */
122 - final void setConnected(boolean connected) {
123 this.connected = connected; 112 this.connected = connected;
124 }; 113 };
125 114
126 - /** 115 + @Override
127 - * Sets the Netty Channel this switch instance is associated with.
128 - * <p>
129 - * Called immediately after instantiation
130 - *
131 - * @param channel the channel
132 - */
133 public final void setChannel(Channel channel) { 116 public final void setChannel(Channel channel) {
134 this.channel = channel; 117 this.channel = channel;
135 }; 118 };
...@@ -138,41 +121,32 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -138,41 +121,32 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
138 // Switch features related 121 // Switch features related
139 //************************ 122 //************************
140 123
141 - /** 124 + @Override
142 - * Gets the datapathId of the switch.
143 - *
144 - * @return the switch buffers
145 - */
146 public final long getId() { 125 public final long getId() {
147 return this.dpid.value(); 126 return this.dpid.value();
148 }; 127 };
149 128
150 - /** 129 + @Override
151 - * Gets a string version of the ID for this switch.
152 - *
153 - * @return string version of the ID
154 - */
155 public final String getStringId() { 130 public final String getStringId() {
156 return this.dpid.toString(); 131 return this.dpid.toString();
157 } 132 }
158 133
134 + @Override
159 public final void setOFVersion(OFVersion ofV) { 135 public final void setOFVersion(OFVersion ofV) {
160 this.ofVersion = ofV; 136 this.ofVersion = ofV;
161 } 137 }
162 138
163 - void setTableFull(boolean full) { 139 + @Override
140 + public void setTableFull(boolean full) {
164 this.tableFull = full; 141 this.tableFull = full;
165 } 142 }
166 143
144 + @Override
167 public void setFeaturesReply(OFFeaturesReply featuresReply) { 145 public void setFeaturesReply(OFFeaturesReply featuresReply) {
168 this.features = featuresReply; 146 this.features = featuresReply;
169 } 147 }
170 148
171 - /** 149 + @Override
172 - * Let peoeple know if you support Nicira style role requests.
173 - *
174 - * @return support Nicira roles or not.
175 - */
176 public abstract Boolean supportNxRole(); 150 public abstract Boolean supportNxRole();
177 151
178 //************************ 152 //************************
...@@ -183,65 +157,80 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -183,65 +157,80 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
183 * 157 *
184 * @param m the actual message 158 * @param m the actual message
185 */ 159 */
160 + @Override
186 public final void handleMessage(OFMessage m) { 161 public final void handleMessage(OFMessage m) {
187 this.agent.processMessage(m); 162 this.agent.processMessage(m);
188 } 163 }
189 164
165 + @Override
190 public RoleState getRole() { 166 public RoleState getRole() {
191 return role; 167 return role;
192 }; 168 };
193 169
194 - final boolean addConnectedSwitch() { 170 + @Override
195 - return this.agent.addConnectedSwitch(this.getId(), this); 171 + public final boolean connectSwitch() {
172 + return this.agent.addConnectedSwitch(dpid, this);
196 } 173 }
197 174
198 - final boolean addActivatedMasterSwitch() { 175 + @Override
199 - return this.agent.addActivatedMasterSwitch(this.getId(), this); 176 + public final boolean activateMasterSwitch() {
177 + return this.agent.addActivatedMasterSwitch(dpid, this);
200 } 178 }
201 179
202 - final boolean addActivatedEqualSwitch() { 180 + @Override
203 - return this.agent.addActivatedEqualSwitch(this.getId(), this); 181 + public final boolean activateEqualSwitch() {
182 + return this.agent.addActivatedEqualSwitch(dpid, this);
204 } 183 }
205 184
206 - final void transitionToEqualSwitch() { 185 + @Override
207 - this.agent.transitionToEqualSwitch(this.getId()); 186 + public final void transitionToEqualSwitch() {
187 + this.agent.transitionToEqualSwitch(dpid);
208 } 188 }
209 189
210 - final void transitionToMasterSwitch() { 190 + @Override
211 - this.agent.transitionToMasterSwitch(this.getId()); 191 + public final void transitionToMasterSwitch() {
192 + this.agent.transitionToMasterSwitch(dpid);
212 } 193 }
213 194
214 - final void removeConnectedSwitch() { 195 + @Override
215 - this.agent.removeConnectedSwitch(this.getId()); 196 + public final void removeConnectedSwitch() {
197 + this.agent.removeConnectedSwitch(dpid);
216 } 198 }
217 199
218 - protected OFFactory factory() { 200 + @Override
201 + public OFFactory factory() {
219 return OFFactories.getFactory(ofVersion); 202 return OFFactories.getFactory(ofVersion);
220 } 203 }
221 204
205 + @Override
222 public void setPortDescReply(OFPortDescStatsReply portDescReply) { 206 public void setPortDescReply(OFPortDescStatsReply portDescReply) {
223 this.ports = portDescReply; 207 this.ports = portDescReply;
224 } 208 }
225 209
210 + @Override
226 public abstract void startDriverHandshake(); 211 public abstract void startDriverHandshake();
227 212
213 + @Override
228 public abstract boolean isDriverHandshakeComplete(); 214 public abstract boolean isDriverHandshakeComplete();
229 215
216 + @Override
230 public abstract void processDriverHandshakeMessage(OFMessage m); 217 public abstract void processDriverHandshakeMessage(OFMessage m);
231 218
219 + @Override
232 public void setRole(RoleState role) { 220 public void setRole(RoleState role) {
233 try { 221 try {
234 if (this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE)) { 222 if (this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE)) {
235 this.role = role; 223 this.role = role;
236 } 224 }
237 } catch (IOException e) { 225 } catch (IOException e) {
238 - log.error("Unable to write to switch {}.", this.dpid); 226 + log.error("Unable to write to switch {}.", this.dpid);
239 } 227 }
240 } 228 }
241 229
242 // Role Handling 230 // Role Handling
243 231
244 - void handleRole(OFMessage m) throws SwitchStateException { 232 + @Override
233 + public void handleRole(OFMessage m) throws SwitchStateException {
245 RoleReplyInfo rri = roleMan.extractOFRoleReply((OFRoleReply) m); 234 RoleReplyInfo rri = roleMan.extractOFRoleReply((OFRoleReply) m);
246 RoleRecvStatus rrs = roleMan.deliverRoleReply(rri); 235 RoleRecvStatus rrs = roleMan.deliverRoleReply(rri);
247 if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) { 236 if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
...@@ -254,7 +243,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -254,7 +243,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
254 } 243 }
255 } 244 }
256 245
257 - void handleNiciraRole(OFMessage m) throws SwitchStateException { 246 + @Override
247 + public void handleNiciraRole(OFMessage m) throws SwitchStateException {
258 RoleState r = this.roleMan.extractNiciraRoleReply((OFExperimenter) m); 248 RoleState r = this.roleMan.extractNiciraRoleReply((OFExperimenter) m);
259 if (r == null) { 249 if (r == null) {
260 // The message wasn't really a Nicira role reply. We just 250 // The message wasn't really a Nicira role reply. We just
...@@ -274,7 +264,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -274,7 +264,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
274 } 264 }
275 } 265 }
276 266
277 - boolean handleRoleError(OFErrorMsg error) { 267 + @Override
268 + public boolean handleRoleError(OFErrorMsg error) {
278 try { 269 try {
279 return RoleRecvStatus.OTHER_EXPECTATION != this.roleMan.deliverError(error); 270 return RoleRecvStatus.OTHER_EXPECTATION != this.roleMan.deliverError(error);
280 } catch (SwitchStateException e) { 271 } catch (SwitchStateException e) {
...@@ -283,25 +274,39 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch { ...@@ -283,25 +274,39 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
283 return true; 274 return true;
284 } 275 }
285 276
286 - void reassertRole() { 277 + @Override
278 + public void reassertRole() {
287 if (this.getRole() == RoleState.MASTER) { 279 if (this.getRole() == RoleState.MASTER) {
288 this.setRole(RoleState.MASTER); 280 this.setRole(RoleState.MASTER);
289 } 281 }
290 } 282 }
291 283
292 - void setAgent(OpenFlowSwitchAgent ag) { 284 + @Override
293 - this.agent = ag; 285 + public final void setAgent(OpenFlowAgent ag) {
286 + if (this.agent == null) {
287 + this.agent = ag;
288 + }
289 + }
290 +
291 + @Override
292 + public final void setRoleHandler(RoleHandler roleHandler) {
293 + if (this.roleMan == null) {
294 + this.roleMan = roleHandler;
295 + }
294 } 296 }
295 297
296 - public void setSwitchDescription(OFDescStatsReply desc) { 298 + @Override
297 - // TODO Auto-generated method stub 299 + public void setSwitchDescription(OFDescStatsReply d) {
300 + this.desc = d;
298 } 301 }
299 302
300 - protected int getNextTransactionId() { 303 + @Override
304 + public int getNextTransactionId() {
301 return this.xidCounter.getAndIncrement(); 305 return this.xidCounter.getAndIncrement();
302 } 306 }
303 307
304 - protected List<OFPortDesc> getPorts() { 308 + @Override
309 + public List<OFPortDesc> getPorts() {
305 return Collections.unmodifiableList(ports.getEntries()); 310 return Collections.unmodifiableList(ports.getEntries());
306 } 311 }
307 312
......
1 +package org.onlab.onos.of.controller.driver;
2 +
3 +import org.onlab.onos.of.controller.Dpid;
4 +import org.onlab.onos.of.controller.OpenFlowSwitch;
5 +import org.projectfloodlight.openflow.protocol.OFMessage;
6 +
7 +/**
8 + * Responsible for keeping track of the current set of switches
9 + * connected to the system. As well as whether they are in Master
10 + * role or not.
11 + *
12 + */
13 +public interface OpenFlowAgent {
14 +
15 + /**
16 + * Add a switch that has just connected to the system.
17 + * @param dpid the dpid to add
18 + * @param sw the actual switch object.
19 + * @return true if added, false otherwise.
20 + */
21 + public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw);
22 +
23 + /**
24 + * Checks if the activation for this switch is valid.
25 + * @param dpid the dpid to check
26 + * @return true if valid, false otherwise
27 + */
28 + public boolean validActivation(Dpid dpid);
29 +
30 + /**
31 + * Called when a switch is activated, with this controller's role as MASTER.
32 + * @param dpid the dpid to add.
33 + * @param sw the actual switch
34 + * @return true if added, false otherwise.
35 + */
36 + public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw);
37 +
38 + /**
39 + * Called when a switch is activated, with this controller's role as EQUAL.
40 + * @param dpid the dpid to add.
41 + * @param sw the actual switch
42 + * @return true if added, false otherwise.
43 + */
44 + public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw);
45 +
46 + /**
47 + * Called when this controller's role for a switch transitions from equal
48 + * to master. For 1.0 switches, we internally refer to the role 'slave' as
49 + * 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'.
50 + * @param dpid the dpid to transistion.
51 + */
52 + public void transitionToMasterSwitch(Dpid dpid);
53 +
54 + /**
55 + * Called when this controller's role for a switch transitions to equal.
56 + * For 1.0 switches, we internally refer to the role 'slave' as
57 + * 'equal'.
58 + * @param dpid the dpid to transistion.
59 + */
60 + public void transitionToEqualSwitch(Dpid dpid);
61 +
62 + /**
63 + * Clear all state in controller switch maps for a switch that has
64 + * disconnected from the local controller. Also release control for
65 + * that switch from the global repository. Notify switch listeners.
66 + * @param dpid the dpid to remove.
67 + */
68 + public void removeConnectedSwitch(Dpid dpid);
69 +
70 + /**
71 + * Process a message coming from a switch.
72 + * @param m the message to process
73 + */
74 + public void processMessage(OFMessage m);
75 +}
1 +package org.onlab.onos.of.controller.driver;
2 +
3 +import java.util.List;
4 +
5 +import org.jboss.netty.channel.Channel;
6 +import org.onlab.onos.of.controller.OpenFlowSwitch;
7 +import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
8 +import org.projectfloodlight.openflow.protocol.OFErrorMsg;
9 +import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
10 +import org.projectfloodlight.openflow.protocol.OFMessage;
11 +import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
12 +import org.projectfloodlight.openflow.protocol.OFVersion;
13 +
14 +/**
15 + * Represents the driver side of an OpenFlow switch.
16 + * This interface should never be exposed to consumers.
17 + *
18 + */
19 +public interface OpenFlowSwitchDriver extends OpenFlowSwitch {
20 +
21 + /**
22 + * Sets the OpenFlow agent to be used. This method
23 + * can only be called once.
24 + * @param agent the agent to set.
25 + */
26 + public void setAgent(OpenFlowAgent agent);
27 +
28 + /**
29 + * Sets the Role handler object.
30 + * This method can only be called once.
31 + * @param roleHandler the roleHandler class
32 + */
33 + public void setRoleHandler(RoleHandler roleHandler);
34 +
35 + /**
36 + * Reasserts this controllers role to the switch.
37 + * Useful in cases where the switch no longer agrees
38 + * that this controller has the role it claims.
39 + */
40 + public void reassertRole();
41 +
42 + /**
43 + * Handle the situation where the role request triggers an error.
44 + * @param error the error to handle.
45 + * @return true if handled, false if not.
46 + */
47 + public boolean handleRoleError(OFErrorMsg error);
48 +
49 + /**
50 + * If this driver know of Nicira style role messages, these should
51 + * be handled here.
52 + * @param m the role message to handle.
53 + * @throws SwitchStateException if the message received was
54 + * not a nicira role or was malformed.
55 + */
56 + public void handleNiciraRole(OFMessage m) throws SwitchStateException;
57 +
58 + /**
59 + * Handle OF 1.x (where x > 0) role messages.
60 + * @param m the role message to handle
61 + * @throws SwitchStateException if the message received was
62 + * not a nicira role or was malformed.
63 + */
64 + public void handleRole(OFMessage m) throws SwitchStateException;
65 +
66 + /**
67 + * Starts the driver specific handshake process.
68 + */
69 + public void startDriverHandshake();
70 +
71 + /**
72 + * Checks whether the driver specific handshake is complete.
73 + * @return true is finished, false if not.
74 + */
75 + public boolean isDriverHandshakeComplete();
76 +
77 + /**
78 + * Process a message during the driver specific handshake.
79 + * @param m the message to process.
80 + */
81 + public void processDriverHandshakeMessage(OFMessage m);
82 +
83 + /**
84 + * Announce to the OpenFlow agent that this switch has connected.
85 + * @return true if successful, false if duplicate switch.
86 + */
87 + public boolean connectSwitch();
88 +
89 + /**
90 + * Activate this MASTER switch-controller relationship in the OF agent.
91 + * @return true is successful, false is switch has not
92 + * connected or is unknown to the system.
93 + */
94 + public boolean activateMasterSwitch();
95 +
96 + /**
97 + * Activate this EQUAL switch-controller relationship in the OF agent.
98 + * @return true is successful, false is switch has not
99 + * connected or is unknown to the system.
100 + */
101 + public boolean activateEqualSwitch();
102 +
103 + /**
104 + * Transition this switch-controller relationship to an EQUAL state.
105 + */
106 + public void transitionToEqualSwitch();
107 +
108 + /**
109 + * Transition this switch-controller relationship to an Master state.
110 + */
111 + public void transitionToMasterSwitch();
112 +
113 + /**
114 + * Remove this switch from the openflow agent.
115 + */
116 + public void removeConnectedSwitch();
117 +
118 + /**
119 + * Sets the ports on this switch.
120 + * @param portDescReply the port set and descriptions
121 + */
122 + public void setPortDescReply(OFPortDescStatsReply portDescReply);
123 +
124 + /**
125 + * Sets the features reply for this switch.
126 + * @param featuresReply the features to set.
127 + */
128 + public void setFeaturesReply(OFFeaturesReply featuresReply);
129 +
130 + /**
131 + * Sets the switch description.
132 + * @param desc the descriptions
133 + */
134 + public void setSwitchDescription(OFDescStatsReply desc);
135 +
136 + /**
137 + * Gets the next transaction id to use.
138 + * @return the xid
139 + */
140 + public int getNextTransactionId();
141 +
142 +
143 + /**
144 + * Does this switch support Nicira Role messages.
145 + * @return true if supports, false otherwise.
146 + */
147 + public Boolean supportNxRole();
148 +
149 + /**
150 + * Sets the OF version for this switch.
151 + * @param ofV the version to set.
152 + */
153 + public void setOFVersion(OFVersion ofV);
154 +
155 + /**
156 + * Sets this switch has having a full flowtable.
157 + * @param full true if full, false otherswise.
158 + */
159 + public void setTableFull(boolean full);
160 +
161 + /**
162 + * Sets the associated Netty channel for this switch.
163 + * @param channel the Netty channel
164 + */
165 + public void setChannel(Channel channel);
166 +
167 + /**
168 + * Sets whether the switch is connected.
169 + *
170 + * @param connected whether the switch is connected
171 + */
172 + public void setConnected(boolean connected);
173 +
174 + /**
175 + * Checks if the switch is still connected.
176 + *
177 + * @return whether the switch is still connected
178 + */
179 + public boolean isConnected();
180 +
181 + /**
182 + * Writes the message to the output stream
183 + * in a driver specific manner.
184 + *
185 + * @param msg the message to write
186 + */
187 + public void write(OFMessage msg);
188 +
189 + /**
190 + * Writes to the OFMessage list to the output stream
191 + * in a driver specific manner.
192 + *
193 + * @param msgs the messages to be written
194 + */
195 + public void write(List<OFMessage> msgs);
196 +
197 +}
1 +package org.onlab.onos.of.controller.driver;
2 +
3 +import org.onlab.onos.of.controller.Dpid;
4 +import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
5 +import org.projectfloodlight.openflow.protocol.OFVersion;
6 +
7 +/**
8 + * Switch factory which returns concrete switch objects for the
9 + * physical openflow switch in use.
10 + *
11 + */
12 +public interface OpenFlowSwitchDriverFactory {
13 +
14 +
15 + /**
16 + * Constructs the real openflow switch representation.
17 + * @param dpid the dpid for this switch.
18 + * @param desc its description.
19 + * @param ofv the OF version in use
20 + * @return the openflow switch representation.
21 + */
22 + public OpenFlowSwitchDriver getOFSwitchImpl(Dpid dpid,
23 + OFDescStatsReply desc, OFVersion ofv);
24 +}
1 +package org.onlab.onos.of.controller.driver;
2 +
3 +import java.io.IOException;
4 +
5 +import org.onlab.onos.of.controller.RoleState;
6 +import org.projectfloodlight.openflow.protocol.OFErrorMsg;
7 +import org.projectfloodlight.openflow.protocol.OFExperimenter;
8 +import org.projectfloodlight.openflow.protocol.OFRoleReply;
9 +
10 +/**
11 + * Role handling.
12 + *
13 + */
14 +public interface RoleHandler {
15 +
16 + /**
17 + * Extract the role from an OFVendor message.
18 + *
19 + * Extract the role from an OFVendor message if the message is a
20 + * Nicira role reply. Otherwise return null.
21 + *
22 + * @param experimenterMsg The vendor message to parse.
23 + * @return The role in the message if the message is a Nicira role
24 + * reply, null otherwise.
25 + * @throws SwitchStateException If the message is a Nicira role reply
26 + * but the numeric role value is unknown.
27 + */
28 + public RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg)
29 + throws SwitchStateException;
30 +
31 + /**
32 + * Send a role request with the given role to the switch and update
33 + * the pending request and timestamp.
34 + * Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR
35 + * Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it
36 + * in the IOFSwitch driver. If not supported, this method sends nothing
37 + * and returns 'false'. The caller should take appropriate action.
38 + *
39 + * One other optimization we do here is that for OF1.0 switches with
40 + * Nicira role message support, we force the Role.EQUAL to become
41 + * Role.SLAVE, as there is no defined behavior for the Nicira role OTHER.
42 + * We cannot expect it to behave like SLAVE. We don't have this problem with
43 + * OF1.3 switches, because Role.EQUAL is well defined and we can simulate
44 + * SLAVE behavior by using ASYNC messages.
45 + *
46 + * @param role
47 + * @throws IOException
48 + * @returns false if and only if the switch does not support role-request
49 + * messages, according to the switch driver; true otherwise.
50 + */
51 + public boolean sendRoleRequest(RoleState role, RoleRecvStatus exp)
52 + throws IOException;
53 +
54 + /**
55 + * Extract the role information from an OF1.3 Role Reply Message.
56 + * @param h
57 + * @param rrmsg
58 + * @return RoleReplyInfo object
59 + * @throws SwitchStateException
60 + */
61 + public RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg)
62 + throws SwitchStateException;
63 +
64 + /**
65 + * Deliver a received role reply.
66 + *
67 + * Check if a request is pending and if the received reply matches the
68 + * the expected pending reply (we check both role and xid) we set
69 + * the role for the switch/channel.
70 + *
71 + * If a request is pending but doesn't match the reply we ignore it, and
72 + * return
73 + *
74 + * If no request is pending we disconnect with a SwitchStateException
75 + *
76 + * @param rri information about role-reply in format that
77 + * controller can understand.
78 + * @throws SwitchStateException if no request is pending
79 + */
80 + public RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
81 + throws SwitchStateException;
82 +
83 +
84 + /**
85 + * Called if we receive an error message. If the xid matches the
86 + * pending request we handle it otherwise we ignore it.
87 + *
88 + * Note: since we only keep the last pending request we might get
89 + * error messages for earlier role requests that we won't be able
90 + * to handle
91 + */
92 + public RoleRecvStatus deliverError(OFErrorMsg error)
93 + throws SwitchStateException;
94 +
95 +}
1 +package org.onlab.onos.of.controller.driver;
2 +
3 +/**
4 + * When we remove a pending role request we use this enum to indicate how we
5 + * arrived at the decision. When we send a role request to the switch, we
6 + * also use this enum to indicate what we expect back from the switch, so the
7 + * role changer can match the reply to our expectation.
8 + */
9 +public enum RoleRecvStatus {
10 + /** The switch returned an error indicating that roles are not.
11 + * supported*/
12 + UNSUPPORTED,
13 + /** The request timed out. */
14 + NO_REPLY,
15 + /** The reply was old, there is a newer request pending. */
16 + OLD_REPLY,
17 + /**
18 + * The reply's role matched the role that this controller set in the
19 + * request message - invoked either initially at startup or to reassert
20 + * current role.
21 + */
22 + MATCHED_CURRENT_ROLE,
23 + /**
24 + * The reply's role matched the role that this controller set in the
25 + * request message - this is the result of a callback from the
26 + * global registry, followed by a role request sent to the switch.
27 + */
28 + MATCHED_SET_ROLE,
29 + /**
30 + * The reply's role was a response to the query made by this controller.
31 + */
32 + REPLY_QUERY,
33 + /** We received a role reply message from the switch
34 + * but the expectation was unclear, or there was no expectation.
35 + */
36 + OTHER_EXPECTATION,
37 +}
1 +package org.onlab.onos.of.controller.driver;
2 +
3 +import org.onlab.onos.of.controller.RoleState;
4 +import org.projectfloodlight.openflow.types.U64;
5 +
6 +/**
7 + * Helper class returns role reply information in the format understood
8 + * by the controller.
9 + */
10 +public class RoleReplyInfo {
11 + private final RoleState role;
12 + private final U64 genId;
13 + private final long xid;
14 +
15 + public RoleReplyInfo(RoleState role, U64 genId, long xid) {
16 + this.role = role;
17 + this.genId = genId;
18 + this.xid = xid;
19 + }
20 + public RoleState getRole() { return role; }
21 + public U64 getGenId() { return genId; }
22 + public long getXid() { return xid; }
23 + @Override
24 + public String toString() {
25 + return "[Role:" + role + " GenId:" + genId + " Xid:" + xid + "]";
26 + }
27 +}
1 -package org.onlab.onos.of.controller.impl.internal; 1 +package org.onlab.onos.of.controller.driver;
2 2
3 /** 3 /**
4 * Thrown when IOFSwitch.startDriverHandshake() is called more than once. 4 * Thrown when IOFSwitch.startDriverHandshake() is called more than once.
......
1 -package org.onlab.onos.of.controller.impl.internal; 1 +package org.onlab.onos.of.controller.driver;
2 2
3 import org.projectfloodlight.openflow.protocol.OFMessage; 3 import org.projectfloodlight.openflow.protocol.OFMessage;
4 4
......
1 -package org.onlab.onos.of.controller.impl.internal; 1 +package org.onlab.onos.of.controller.driver;
2 2
3 /** 3 /**
4 * Base class for exception thrown by switch driver sub-handshake processing. 4 * Base class for exception thrown by switch driver sub-handshake processing.
......
1 -package org.onlab.onos.of.controller.impl.internal; 1 +package org.onlab.onos.of.controller.driver;
2 2
3 /** 3 /**
4 * Thrown when a switch driver's sub-handshake has not been started but an 4 * Thrown when a switch driver's sub-handshake has not been started but an
......
1 -package org.onlab.onos.of.controller.impl.internal; 1 +package org.onlab.onos.of.controller.driver;
2 2
3 /** 3 /**
4 * Thrown when a switch driver's sub-handshake state-machine receives an 4 * Thrown when a switch driver's sub-handshake state-machine receives an
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
15 * under the License. 15 * under the License.
16 **/ 16 **/
17 17
18 -package org.onlab.onos.of.controller.impl.internal; 18 +package org.onlab.onos.of.controller.driver;
19 19
20 /** 20 /**
21 * This exception indicates an error or unexpected message during 21 * This exception indicates an error or unexpected message during
......
...@@ -30,9 +30,10 @@ import org.jboss.netty.channel.group.ChannelGroup; ...@@ -30,9 +30,10 @@ 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.Dpid;
33 +import org.onlab.onos.of.controller.driver.OpenFlowAgent;
34 +import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
33 import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc; 35 import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
34 import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs; 36 import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
35 -import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent;
36 import org.onlab.onos.of.drivers.DriverManager; 37 import org.onlab.onos.of.drivers.DriverManager;
37 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 38 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
38 import org.projectfloodlight.openflow.protocol.OFFactories; 39 import org.projectfloodlight.openflow.protocol.OFFactories;
...@@ -74,7 +75,7 @@ public class Controller { ...@@ -74,7 +75,7 @@ public class Controller {
74 75
75 // Flag to always flush flow table on switch reconnect (HA or otherwise) 76 // Flag to always flush flow table on switch reconnect (HA or otherwise)
76 protected boolean alwaysClearFlowsOnSwAdd = false; 77 protected boolean alwaysClearFlowsOnSwAdd = false;
77 - private OpenFlowSwitchAgent agent; 78 + private OpenFlowAgent agent;
78 79
79 // Perf. related configuration 80 // Perf. related configuration
80 protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; 81 protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
...@@ -120,17 +121,17 @@ public class Controller { ...@@ -120,17 +121,17 @@ public class Controller {
120 * Tell controller that we're ready to accept switches loop. 121 * Tell controller that we're ready to accept switches loop.
121 */ 122 */
122 @LogMessageDocs({ 123 @LogMessageDocs({
123 - @LogMessageDoc(message = "Listening for switch connections on {address}", 124 + @LogMessageDoc(message = "Listening for switch connections on {address}",
124 - explanation = "The controller is ready and listening for new" + 125 + explanation = "The controller is ready and listening for new" +
125 - " switch connections"), 126 + " switch connections"),
126 - @LogMessageDoc(message = "Storage exception in controller " + 127 + @LogMessageDoc(message = "Storage exception in controller " +
127 - "updates loop; terminating process", 128 + "updates loop; terminating process",
128 - explanation = ERROR_DATABASE, 129 + explanation = ERROR_DATABASE,
129 - recommendation = LogMessageDoc.CHECK_CONTROLLER), 130 + recommendation = LogMessageDoc.CHECK_CONTROLLER),
130 - @LogMessageDoc(level = "ERROR", 131 + @LogMessageDoc(level = "ERROR",
131 - message = "Exception in controller updates loop", 132 + message = "Exception in controller updates loop",
132 - explanation = "Failed to dispatch controller event", 133 + explanation = "Failed to dispatch controller event",
133 - recommendation = LogMessageDoc.GENERIC_ACTION) 134 + recommendation = LogMessageDoc.GENERIC_ACTION)
134 }) 135 })
135 public void run() { 136 public void run() {
136 137
...@@ -221,15 +222,16 @@ public class Controller { ...@@ -221,15 +222,16 @@ public class Controller {
221 * @param desc 222 * @param desc
222 * @return switch instance 223 * @return switch instance
223 */ 224 */
224 - protected AbstractOpenFlowSwitch getOFSwitchInstance(long dpid, 225 + protected OpenFlowSwitchDriver getOFSwitchInstance(long dpid,
225 OFDescStatsReply desc, OFVersion ofv) { 226 OFDescStatsReply desc, OFVersion ofv) {
226 - AbstractOpenFlowSwitch sw = DriverManager.getOFSwitchImpl(new Dpid(dpid), 227 + OpenFlowSwitchDriver sw = DriverManager.getSwitch(new Dpid(dpid),
227 desc, ofv); 228 desc, ofv);
228 sw.setAgent(agent); 229 sw.setAgent(agent);
230 + sw.setRoleHandler(new RoleManager(sw));
229 return sw; 231 return sw;
230 } 232 }
231 233
232 - public void start(OpenFlowSwitchAgent ag) { 234 + public void start(OpenFlowAgent ag) {
233 log.info("Initialising OpenFlow Lib and IO"); 235 log.info("Initialising OpenFlow Lib and IO");
234 this.agent = ag; 236 this.agent = ag;
235 this.init(new HashMap<String, String>()); 237 this.init(new HashMap<String, String>());
......
1 package org.onlab.onos.of.controller.impl.internal; 1 package org.onlab.onos.of.controller.impl.internal;
2 2
3 +import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
3 import org.projectfloodlight.openflow.protocol.OFVersion; 4 import org.projectfloodlight.openflow.protocol.OFVersion;
4 5
5 6
......
...@@ -18,6 +18,8 @@ import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; ...@@ -18,6 +18,8 @@ import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
18 import org.jboss.netty.handler.timeout.IdleStateEvent; 18 import org.jboss.netty.handler.timeout.IdleStateEvent;
19 import org.jboss.netty.handler.timeout.ReadTimeoutException; 19 import org.jboss.netty.handler.timeout.ReadTimeoutException;
20 import org.onlab.onos.of.controller.RoleState; 20 import org.onlab.onos.of.controller.RoleState;
21 +import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
22 +import org.onlab.onos.of.controller.driver.SwitchStateException;
21 import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc; 23 import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
22 import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs; 24 import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
23 import org.projectfloodlight.openflow.exceptions.OFParseError; 25 import org.projectfloodlight.openflow.exceptions.OFParseError;
...@@ -66,7 +68,7 @@ import org.slf4j.LoggerFactory; ...@@ -66,7 +68,7 @@ import org.slf4j.LoggerFactory;
66 class OFChannelHandler extends IdleStateAwareChannelHandler { 68 class OFChannelHandler extends IdleStateAwareChannelHandler {
67 private static final Logger log = LoggerFactory.getLogger(OFChannelHandler.class); 69 private static final Logger log = LoggerFactory.getLogger(OFChannelHandler.class);
68 private final Controller controller; 70 private final Controller controller;
69 - private AbstractOpenFlowSwitch sw; 71 + private OpenFlowSwitchDriver sw;
70 private long thisdpid; // channelHandler cached value of connected switch id 72 private long thisdpid; // channelHandler cached value of connected switch id
71 private Channel channel; 73 private Channel channel;
72 // State needs to be volatile because the HandshakeTimeoutHandler 74 // State needs to be volatile because the HandshakeTimeoutHandler
...@@ -413,7 +415,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -413,7 +415,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
413 OFDescStatsReply drep = (OFDescStatsReply) m; 415 OFDescStatsReply drep = (OFDescStatsReply) m;
414 // Here is where we differentiate between different kinds of switches 416 // Here is where we differentiate between different kinds of switches
415 h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion); 417 h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion);
416 - boolean success = h.sw.addConnectedSwitch(); 418 + boolean success = h.sw.connectSwitch();
417 if (!success) { 419 if (!success) {
418 disconnectDuplicate(h); 420 disconnectDuplicate(h);
419 return; 421 return;
...@@ -431,7 +433,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -431,7 +433,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
431 //Put switch in EQUAL mode until we hear back from the global registry 433 //Put switch in EQUAL mode until we hear back from the global registry
432 log.debug("Setting new switch {} to EQUAL and sending Role request", 434 log.debug("Setting new switch {} to EQUAL and sending Role request",
433 h.sw.getStringId()); 435 h.sw.getStringId());
434 - h.sw.addActivatedEqualSwitch(); 436 + h.sw.activateEqualSwitch();
435 //h.setSwitchRole(RoleState.EQUAL); 437 //h.setSwitchRole(RoleState.EQUAL);
436 h.setSwitchRole(RoleState.MASTER); 438 h.setSwitchRole(RoleState.MASTER);
437 h.sw.startDriverHandshake(); 439 h.sw.startDriverHandshake();
...@@ -489,8 +491,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -489,8 +491,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
489 } 491 }
490 } 492 }
491 } else { 493 } else {
492 - if (m.getType() == OFType.EXPERIMENTER && 494 + if (m.getType() == OFType.EXPERIMENTER &&
493 - ((OFExperimenter) m).getExperimenter() == 495 + ((OFExperimenter) m).getExperimenter() ==
494 RoleManager.NICIRA_EXPERIMENTER) { 496 RoleManager.NICIRA_EXPERIMENTER) {
495 h.sw.handleNiciraRole(m); 497 h.sw.handleNiciraRole(m);
496 } else { 498 } else {
...@@ -848,8 +850,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -848,8 +850,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
848 processOFQueueGetConfigReply(h, (OFQueueGetConfigReply) m); 850 processOFQueueGetConfigReply(h, (OFQueueGetConfigReply) m);
849 break; 851 break;
850 case STATS_REPLY: // multipart_reply in 1.3 852 case STATS_REPLY: // multipart_reply in 1.3
851 - processOFStatisticsReply(h, (OFStatsReply) m); 853 + processOFStatisticsReply(h, (OFStatsReply) m);
852 - break; 854 + break;
853 case EXPERIMENTER: 855 case EXPERIMENTER:
854 processOFExperimenter(h, (OFExperimenter) m); 856 processOFExperimenter(h, (OFExperimenter) m);
855 break; 857 break;
...@@ -916,12 +918,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -916,12 +918,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
916 } 918 }
917 OFFactory factory = (h.ofVersion == OFVersion.OF_13) ? 919 OFFactory factory = (h.ofVersion == OFVersion.OF_13) ?
918 h.controller.getOFMessageFactory13() : h.controller.getOFMessageFactory10(); 920 h.controller.getOFMessageFactory13() : h.controller.getOFMessageFactory10();
919 - OFEchoReply reply = factory 921 + OFEchoReply reply = factory
920 - .buildEchoReply() 922 + .buildEchoReply()
921 - .setXid(m.getXid()) 923 + .setXid(m.getXid())
922 - .setData(m.getData()) 924 + .setData(m.getData())
923 - .build(); 925 + .build();
924 - h.channel.write(Collections.singletonList(reply)); 926 + h.channel.write(Collections.singletonList(reply));
925 } 927 }
926 928
927 void processOFEchoReply(OFChannelHandler h, OFEchoReply m) 929 void processOFEchoReply(OFChannelHandler h, OFEchoReply m)
...@@ -1044,41 +1046,41 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -1044,41 +1046,41 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
1044 message = "Disconnecting switch {switch} due to read timeout", 1046 message = "Disconnecting switch {switch} due to read timeout",
1045 explanation = "The connected switch has failed to send any " 1047 explanation = "The connected switch has failed to send any "
1046 + "messages or respond to echo requests", 1048 + "messages or respond to echo requests",
1047 - recommendation = LogMessageDoc.CHECK_SWITCH), 1049 + recommendation = LogMessageDoc.CHECK_SWITCH),
1048 @LogMessageDoc(level = "ERROR", 1050 @LogMessageDoc(level = "ERROR",
1049 - message = "Disconnecting switch {switch}: failed to " 1051 + message = "Disconnecting switch {switch}: failed to "
1050 - + "complete handshake", 1052 + + "complete handshake",
1051 - explanation = "The switch did not respond correctly " 1053 + explanation = "The switch did not respond correctly "
1052 - + "to handshake messages", 1054 + + "to handshake messages",
1053 - recommendation = LogMessageDoc.CHECK_SWITCH), 1055 + recommendation = LogMessageDoc.CHECK_SWITCH),
1054 - @LogMessageDoc(level = "ERROR", 1056 + @LogMessageDoc(level = "ERROR",
1055 - message = "Disconnecting switch {switch} due to IO Error: {}", 1057 + message = "Disconnecting switch {switch} due to IO Error: {}",
1056 - explanation = "There was an error communicating with the switch", 1058 + explanation = "There was an error communicating with the switch",
1057 - recommendation = LogMessageDoc.CHECK_SWITCH), 1059 + recommendation = LogMessageDoc.CHECK_SWITCH),
1058 - @LogMessageDoc(level = "ERROR", 1060 + @LogMessageDoc(level = "ERROR",
1059 - message = "Disconnecting switch {switch} due to switch " 1061 + message = "Disconnecting switch {switch} due to switch "
1060 - + "state error: {error}", 1062 + + "state error: {error}",
1061 - explanation = "The switch sent an unexpected message", 1063 + explanation = "The switch sent an unexpected message",
1062 - recommendation = LogMessageDoc.CHECK_SWITCH), 1064 + recommendation = LogMessageDoc.CHECK_SWITCH),
1063 - @LogMessageDoc(level = "ERROR", 1065 + @LogMessageDoc(level = "ERROR",
1064 - message = "Disconnecting switch {switch} due to " 1066 + message = "Disconnecting switch {switch} due to "
1065 - + "message parse failure", 1067 + + "message parse failure",
1066 - explanation = "Could not parse a message from the switch", 1068 + explanation = "Could not parse a message from the switch",
1067 - recommendation = LogMessageDoc.CHECK_SWITCH), 1069 + recommendation = LogMessageDoc.CHECK_SWITCH),
1068 - @LogMessageDoc(level = "ERROR", 1070 + @LogMessageDoc(level = "ERROR",
1069 - message = "Terminating controller due to storage exception", 1071 + message = "Terminating controller due to storage exception",
1070 - explanation = Controller.ERROR_DATABASE, 1072 + explanation = Controller.ERROR_DATABASE,
1071 - recommendation = LogMessageDoc.CHECK_CONTROLLER), 1073 + recommendation = LogMessageDoc.CHECK_CONTROLLER),
1072 - @LogMessageDoc(level = "ERROR", 1074 + @LogMessageDoc(level = "ERROR",
1073 - message = "Could not process message: queue full", 1075 + message = "Could not process message: queue full",
1074 - explanation = "OpenFlow messages are arriving faster than " 1076 + explanation = "OpenFlow messages are arriving faster than "
1075 - + "the controller can process them.", 1077 + + "the controller can process them.",
1076 - recommendation = LogMessageDoc.CHECK_CONTROLLER), 1078 + recommendation = LogMessageDoc.CHECK_CONTROLLER),
1077 - @LogMessageDoc(level = "ERROR", 1079 + @LogMessageDoc(level = "ERROR",
1078 - message = "Error while processing message " 1080 + message = "Error while processing message "
1079 - + "from switch {switch} {cause}", 1081 + + "from switch {switch} {cause}",
1080 - explanation = "An error occurred processing the switch message", 1082 + explanation = "An error occurred processing the switch message",
1081 - recommendation = LogMessageDoc.GENERIC_ACTION) 1083 + recommendation = LogMessageDoc.GENERIC_ACTION)
1082 }) 1084 })
1083 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) 1085 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
1084 throws Exception { 1086 throws Exception {
......
...@@ -15,8 +15,9 @@ import org.onlab.onos.of.controller.OpenFlowSwitch; ...@@ -15,8 +15,9 @@ import org.onlab.onos.of.controller.OpenFlowSwitch;
15 import org.onlab.onos.of.controller.OpenFlowSwitchListener; 15 import org.onlab.onos.of.controller.OpenFlowSwitchListener;
16 import org.onlab.onos.of.controller.PacketListener; 16 import org.onlab.onos.of.controller.PacketListener;
17 import org.onlab.onos.of.controller.RoleState; 17 import org.onlab.onos.of.controller.RoleState;
18 +import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
19 +import org.onlab.onos.of.controller.driver.OpenFlowAgent;
18 import org.projectfloodlight.openflow.protocol.OFMessage; 20 import org.projectfloodlight.openflow.protocol.OFMessage;
19 -import org.projectfloodlight.openflow.util.HexString;
20 import org.slf4j.Logger; 21 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory; 22 import org.slf4j.LoggerFactory;
22 23
...@@ -27,12 +28,12 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -27,12 +28,12 @@ public class OpenFlowControllerImpl implements OpenFlowController {
27 private static final Logger log = 28 private static final Logger log =
28 LoggerFactory.getLogger(OpenFlowControllerImpl.class); 29 LoggerFactory.getLogger(OpenFlowControllerImpl.class);
29 30
30 - protected ConcurrentHashMap<Long, OpenFlowSwitch> connectedSwitches = 31 + protected ConcurrentHashMap<Dpid, OpenFlowSwitch> connectedSwitches =
31 - new ConcurrentHashMap<Long, OpenFlowSwitch>(); 32 + new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
32 - protected ConcurrentHashMap<Long, OpenFlowSwitch> activeMasterSwitches = 33 + protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeMasterSwitches =
33 - new ConcurrentHashMap<Long, OpenFlowSwitch>(); 34 + new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
34 - protected ConcurrentHashMap<Long, OpenFlowSwitch> activeEqualSwitches = 35 + protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeEqualSwitches =
35 - new ConcurrentHashMap<Long, OpenFlowSwitch>(); 36 + new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
36 37
37 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent(); 38 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
38 protected ArrayList<OpenFlowSwitchListener> ofEventListener = 39 protected ArrayList<OpenFlowSwitchListener> ofEventListener =
...@@ -118,12 +119,13 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -118,12 +119,13 @@ public class OpenFlowControllerImpl implements OpenFlowController {
118 ((AbstractOpenFlowSwitch) getSwitch(dpid)).setRole(role); 119 ((AbstractOpenFlowSwitch) getSwitch(dpid)).setRole(role);
119 } 120 }
120 121
121 - public class OpenFlowSwitchAgent { 122 + public class OpenFlowSwitchAgent implements OpenFlowAgent {
122 123
123 private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class); 124 private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
124 - private Lock switchLock = new ReentrantLock(); 125 + private final Lock switchLock = new ReentrantLock();
125 126
126 - public boolean addConnectedSwitch(long dpid, AbstractOpenFlowSwitch sw) { 127 + @Override
128 + public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
127 if (connectedSwitches.get(dpid) != null) { 129 if (connectedSwitches.get(dpid) != null) {
128 log.error("Trying to add connectedSwitch but found a previous " 130 log.error("Trying to add connectedSwitch but found a previous "
129 + "value for dpid: {}", dpid); 131 + "value for dpid: {}", dpid);
...@@ -132,17 +134,18 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -132,17 +134,18 @@ public class OpenFlowControllerImpl implements OpenFlowController {
132 log.error("Added switch {}", dpid); 134 log.error("Added switch {}", dpid);
133 connectedSwitches.put(dpid, sw); 135 connectedSwitches.put(dpid, sw);
134 for (OpenFlowSwitchListener l : ofEventListener) { 136 for (OpenFlowSwitchListener l : ofEventListener) {
135 - l.switchAdded(new Dpid(dpid)); 137 + l.switchAdded(dpid);
136 } 138 }
137 return true; 139 return true;
138 } 140 }
139 } 141 }
140 142
141 - private boolean validActivation(long dpid) { 143 + @Override
144 + public boolean validActivation(Dpid dpid) {
142 if (connectedSwitches.get(dpid) == null) { 145 if (connectedSwitches.get(dpid) == null) {
143 log.error("Trying to activate switch but is not in " 146 log.error("Trying to activate switch but is not in "
144 + "connected switches: dpid {}. Aborting ..", 147 + "connected switches: dpid {}. Aborting ..",
145 - HexString.toHexString(dpid)); 148 + dpid);
146 return false; 149 return false;
147 } 150 }
148 if (activeMasterSwitches.get(dpid) != null || 151 if (activeMasterSwitches.get(dpid) != null ||
...@@ -150,18 +153,17 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -150,18 +153,17 @@ public class OpenFlowControllerImpl implements OpenFlowController {
150 log.error("Trying to activate switch but it is already " 153 log.error("Trying to activate switch but it is already "
151 + "activated: dpid {}. Found in activeMaster: {} " 154 + "activated: dpid {}. Found in activeMaster: {} "
152 + "Found in activeEqual: {}. Aborting ..", new Object[] { 155 + "Found in activeEqual: {}. Aborting ..", new Object[] {
153 - HexString.toHexString(dpid), 156 + dpid,
154 (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y', 157 (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
155 - (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'}); 158 + (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
156 return false; 159 return false;
157 } 160 }
158 return true; 161 return true;
159 } 162 }
160 163
161 - /** 164 +
162 - * Called when a switch is activated, with this controller's role as MASTER. 165 + @Override
163 - */ 166 + public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) {
164 - protected boolean addActivatedMasterSwitch(long dpid, AbstractOpenFlowSwitch sw) {
165 switchLock.lock(); 167 switchLock.lock();
166 try { 168 try {
167 if (!validActivation(dpid)) { 169 if (!validActivation(dpid)) {
...@@ -172,31 +174,25 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -172,31 +174,25 @@ public class OpenFlowControllerImpl implements OpenFlowController {
172 } finally { 174 } finally {
173 switchLock.unlock(); 175 switchLock.unlock();
174 } 176 }
175 - } 177 + }
176 178
177 - /** 179 + @Override
178 - * Called when a switch is activated, with this controller's role as EQUAL. 180 + public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) {
179 - */
180 - protected boolean addActivatedEqualSwitch(long dpid, AbstractOpenFlowSwitch sw) {
181 switchLock.lock(); 181 switchLock.lock();
182 try { 182 try {
183 - if (!validActivation(dpid)) { 183 + if (!validActivation(dpid)) {
184 - return false; 184 + return false;
185 - } 185 + }
186 - activeEqualSwitches.put(dpid, sw); 186 + activeEqualSwitches.put(dpid, sw);
187 - log.info("Added Activated EQUAL Switch {}", dpid); 187 + log.info("Added Activated EQUAL Switch {}", dpid);
188 - return true; 188 + return true;
189 } finally { 189 } finally {
190 switchLock.unlock(); 190 switchLock.unlock();
191 } 191 }
192 } 192 }
193 193
194 - /** 194 + @Override
195 - * Called when this controller's role for a switch transitions from equal 195 + public void transitionToMasterSwitch(Dpid dpid) {
196 - * to master. For 1.0 switches, we internally refer to the role 'slave' as
197 - * 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'.
198 - */
199 - protected void transitionToMasterSwitch(long dpid) {
200 switchLock.lock(); 196 switchLock.lock();
201 try { 197 try {
202 if (activeMasterSwitches.containsKey(dpid)) { 198 if (activeMasterSwitches.containsKey(dpid)) {
...@@ -215,12 +211,8 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -215,12 +211,8 @@ public class OpenFlowControllerImpl implements OpenFlowController {
215 } 211 }
216 212
217 213
218 - /** 214 + @Override
219 - * Called when this controller's role for a switch transitions to equal. 215 + public void transitionToEqualSwitch(Dpid dpid) {
220 - * For 1.0 switches, we internally refer to the role 'slave' as
221 - * 'equal'.
222 - */
223 - protected void transitionToEqualSwitch(long dpid) {
224 switchLock.lock(); 216 switchLock.lock();
225 try { 217 try {
226 if (activeEqualSwitches.containsKey(dpid)) { 218 if (activeEqualSwitches.containsKey(dpid)) {
...@@ -239,22 +231,19 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -239,22 +231,19 @@ public class OpenFlowControllerImpl implements OpenFlowController {
239 231
240 } 232 }
241 233
242 - /** 234 + @Override
243 - * Clear all state in controller switch maps for a switch that has 235 + public void removeConnectedSwitch(Dpid dpid) {
244 - * disconnected from the local controller. Also release control for
245 - * that switch from the global repository. Notify switch listeners.
246 - */
247 - public void removeConnectedSwitch(long dpid) {
248 connectedSwitches.remove(dpid); 236 connectedSwitches.remove(dpid);
249 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid); 237 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
250 if (sw == null) { 238 if (sw == null) {
251 sw = activeEqualSwitches.remove(dpid); 239 sw = activeEqualSwitches.remove(dpid);
252 } 240 }
253 for (OpenFlowSwitchListener l : ofEventListener) { 241 for (OpenFlowSwitchListener l : ofEventListener) {
254 - l.switchRemoved(new Dpid(dpid)); 242 + l.switchRemoved(dpid);
255 } 243 }
256 } 244 }
257 245
246 + @Override
258 public void processMessage(OFMessage m) { 247 public void processMessage(OFMessage m) {
259 processPacket(m); 248 processPacket(m);
260 } 249 }
......
...@@ -4,6 +4,11 @@ import java.io.IOException; ...@@ -4,6 +4,11 @@ import java.io.IOException;
4 import java.util.Collections; 4 import java.util.Collections;
5 5
6 import org.onlab.onos.of.controller.RoleState; 6 import org.onlab.onos.of.controller.RoleState;
7 +import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
8 +import org.onlab.onos.of.controller.driver.RoleHandler;
9 +import org.onlab.onos.of.controller.driver.RoleRecvStatus;
10 +import org.onlab.onos.of.controller.driver.RoleReplyInfo;
11 +import org.onlab.onos.of.controller.driver.SwitchStateException;
7 import org.projectfloodlight.openflow.protocol.OFControllerRole; 12 import org.projectfloodlight.openflow.protocol.OFControllerRole;
8 import org.projectfloodlight.openflow.protocol.OFErrorMsg; 13 import org.projectfloodlight.openflow.protocol.OFErrorMsg;
9 import org.projectfloodlight.openflow.protocol.OFErrorType; 14 import org.projectfloodlight.openflow.protocol.OFErrorType;
...@@ -35,7 +40,7 @@ import org.slf4j.LoggerFactory; ...@@ -35,7 +40,7 @@ import org.slf4j.LoggerFactory;
35 * a new request is submitted before the timeout triggers. If necessary 40 * a new request is submitted before the timeout triggers. If necessary
36 * we could work around that though. 41 * we could work around that though.
37 */ 42 */
38 -class RoleManager { 43 +class RoleManager implements RoleHandler {
39 protected static final long NICIRA_EXPERIMENTER = 0x2320; 44 protected static final long NICIRA_EXPERIMENTER = 0x2320;
40 45
41 private static Logger log = LoggerFactory.getLogger(RoleManager.class); 46 private static Logger log = LoggerFactory.getLogger(RoleManager.class);
...@@ -49,10 +54,10 @@ class RoleManager { ...@@ -49,10 +54,10 @@ class RoleManager {
49 54
50 // the expectation set by the caller for the returned role 55 // the expectation set by the caller for the returned role
51 private RoleRecvStatus expectation; 56 private RoleRecvStatus expectation;
52 - private AbstractOpenFlowSwitch sw; 57 + private final OpenFlowSwitchDriver sw;
53 58
54 59
55 - public RoleManager(AbstractOpenFlowSwitch sw) { 60 + public RoleManager(OpenFlowSwitchDriver sw) {
56 this.requestPending = false; 61 this.requestPending = false;
57 this.pendingXid = -1; 62 this.pendingXid = -1;
58 this.pendingRole = null; 63 this.pendingRole = null;
...@@ -122,33 +127,13 @@ class RoleManager { ...@@ -122,33 +127,13 @@ class RoleManager {
122 return xid; 127 return xid;
123 } 128 }
124 129
125 - /** 130 + @Override
126 - * Send a role request with the given role to the switch and update 131 + public synchronized boolean sendRoleRequest(RoleState role, RoleRecvStatus exp)
127 - * the pending request and timestamp.
128 - * Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR
129 - * Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it
130 - * in the IOFSwitch driver. If not supported, this method sends nothing
131 - * and returns 'false'. The caller should take appropriate action.
132 - *
133 - * One other optimization we do here is that for OF1.0 switches with
134 - * Nicira role message support, we force the Role.EQUAL to become
135 - * Role.SLAVE, as there is no defined behavior for the Nicira role OTHER.
136 - * We cannot expect it to behave like SLAVE. We don't have this problem with
137 - * OF1.3 switches, because Role.EQUAL is well defined and we can simulate
138 - * SLAVE behavior by using ASYNC messages.
139 - *
140 - * @param role
141 - * @throws IOException
142 - * @returns false if and only if the switch does not support role-request
143 - * messages, according to the switch driver; true otherwise.
144 - */
145 - synchronized boolean sendRoleRequest(RoleState role, RoleRecvStatus exp)
146 throws IOException { 132 throws IOException {
147 this.expectation = exp; 133 this.expectation = exp;
148 134
149 if (sw.factory().getVersion() == OFVersion.OF_10) { 135 if (sw.factory().getVersion() == OFVersion.OF_10) {
150 - Boolean supportsNxRole = (Boolean) 136 + Boolean supportsNxRole = sw.supportNxRole();
151 - sw.supportNxRole();
152 if (!supportsNxRole) { 137 if (!supportsNxRole) {
153 log.debug("Switch driver indicates no support for Nicira " 138 log.debug("Switch driver indicates no support for Nicira "
154 + "role request messages. Not sending ..."); 139 + "role request messages. Not sending ...");
...@@ -189,23 +174,9 @@ class RoleManager { ...@@ -189,23 +174,9 @@ class RoleManager {
189 174
190 } 175 }
191 176
192 - /** 177 +
193 - * Deliver a received role reply. 178 + @Override
194 - * 179 + public synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
195 - * Check if a request is pending and if the received reply matches the
196 - * the expected pending reply (we check both role and xid) we set
197 - * the role for the switch/channel.
198 - *
199 - * If a request is pending but doesn't match the reply we ignore it, and
200 - * return
201 - *
202 - * If no request is pending we disconnect with a SwitchStateException
203 - *
204 - * @param RoleReplyInfo information about role-reply in format that
205 - * controller can understand.
206 - * @throws SwitchStateException if no request is pending
207 - */
208 - synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
209 throws SwitchStateException { 180 throws SwitchStateException {
210 if (!requestPending) { 181 if (!requestPending) {
211 RoleState currentRole = (sw != null) ? sw.getRole() : null; 182 RoleState currentRole = (sw != null) ? sw.getRole() : null;
...@@ -280,12 +251,13 @@ class RoleManager { ...@@ -280,12 +251,13 @@ class RoleManager {
280 * error messages for earlier role requests that we won't be able 251 * error messages for earlier role requests that we won't be able
281 * to handle 252 * to handle
282 */ 253 */
283 - synchronized RoleRecvStatus deliverError(OFErrorMsg error) 254 + @Override
255 + public synchronized RoleRecvStatus deliverError(OFErrorMsg error)
284 throws SwitchStateException { 256 throws SwitchStateException {
285 if (!requestPending) { 257 if (!requestPending) {
286 log.debug("Received an error msg from sw {}, but no pending " 258 log.debug("Received an error msg from sw {}, but no pending "
287 + "requests in role-changer; not handling ...", 259 + "requests in role-changer; not handling ...",
288 - sw.getStringId()); 260 + sw.getStringId());
289 return RoleRecvStatus.OTHER_EXPECTATION; 261 return RoleRecvStatus.OTHER_EXPECTATION;
290 } 262 }
291 if (pendingXid != error.getXid()) { 263 if (pendingXid != error.getXid()) {
...@@ -353,7 +325,8 @@ class RoleManager { ...@@ -353,7 +325,8 @@ class RoleManager {
353 * @throws SwitchStateException If the message is a Nicira role reply 325 * @throws SwitchStateException If the message is a Nicira role reply
354 * but the numeric role value is unknown. 326 * but the numeric role value is unknown.
355 */ 327 */
356 - protected RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg) 328 + @Override
329 + public RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg)
357 throws SwitchStateException { 330 throws SwitchStateException {
358 int vendor = (int) experimenterMsg.getExperimenter(); 331 int vendor = (int) experimenterMsg.getExperimenter();
359 if (vendor != 0x2320) { 332 if (vendor != 0x2320) {
...@@ -389,72 +362,14 @@ class RoleManager { ...@@ -389,72 +362,14 @@ class RoleManager {
389 } 362 }
390 363
391 /** 364 /**
392 - * When we remove a pending role request we use this enum to indicate how we
393 - * arrived at the decision. When we send a role request to the switch, we
394 - * also use this enum to indicate what we expect back from the switch, so the
395 - * role changer can match the reply to our expectation.
396 - */
397 - public enum RoleRecvStatus {
398 - /** The switch returned an error indicating that roles are not.
399 - * supported*/
400 - UNSUPPORTED,
401 - /** The request timed out. */
402 - NO_REPLY,
403 - /** The reply was old, there is a newer request pending. */
404 - OLD_REPLY,
405 - /**
406 - * The reply's role matched the role that this controller set in the
407 - * request message - invoked either initially at startup or to reassert
408 - * current role.
409 - */
410 - MATCHED_CURRENT_ROLE,
411 - /**
412 - * The reply's role matched the role that this controller set in the
413 - * request message - this is the result of a callback from the
414 - * global registry, followed by a role request sent to the switch.
415 - */
416 - MATCHED_SET_ROLE,
417 - /**
418 - * The reply's role was a response to the query made by this controller.
419 - */
420 - REPLY_QUERY,
421 - /** We received a role reply message from the switch
422 - * but the expectation was unclear, or there was no expectation.
423 - */
424 - OTHER_EXPECTATION,
425 - }
426 -
427 - /**
428 - * Helper class returns role reply information in the format understood
429 - * by the controller.
430 - */
431 - protected static class RoleReplyInfo {
432 - private RoleState role;
433 - private U64 genId;
434 - private long xid;
435 -
436 - RoleReplyInfo(RoleState role, U64 genId, long xid) {
437 - this.role = role;
438 - this.genId = genId;
439 - this.xid = xid;
440 - }
441 - public RoleState getRole() { return role; }
442 - public U64 getGenId() { return genId; }
443 - public long getXid() { return xid; }
444 - @Override
445 - public String toString() {
446 - return "[Role:" + role + " GenId:" + genId + " Xid:" + xid + "]";
447 - }
448 - }
449 -
450 - /**
451 * Extract the role information from an OF1.3 Role Reply Message. 365 * Extract the role information from an OF1.3 Role Reply Message.
452 * @param h 366 * @param h
453 - * @param rrmsg 367 + * @param rrmsg the role message
454 * @return RoleReplyInfo object 368 * @return RoleReplyInfo object
455 - * @throws SwitchStateException 369 + * @throws SwitchStateException if the role information could not be extracted.
456 */ 370 */
457 - protected RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg) 371 + @Override
372 + public RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg)
458 throws SwitchStateException { 373 throws SwitchStateException {
459 OFControllerRole cr = rrmsg.getRole(); 374 OFControllerRole cr = rrmsg.getRole();
460 RoleState role = null; 375 RoleState role = null;
......
...@@ -3,11 +3,9 @@ package org.onlab.onos.of.drivers; ...@@ -3,11 +3,9 @@ package org.onlab.onos.of.drivers;
3 3
4 4
5 import org.onlab.onos.of.controller.Dpid; 5 import org.onlab.onos.of.controller.Dpid;
6 -import org.onlab.onos.of.controller.RoleState; 6 +import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
7 -import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch; 7 +import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriverFactory;
8 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 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; 9 import org.projectfloodlight.openflow.protocol.OFVersion;
12 import org.slf4j.Logger; 10 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
...@@ -16,7 +14,7 @@ import org.slf4j.LoggerFactory; ...@@ -16,7 +14,7 @@ import org.slf4j.LoggerFactory;
16 * A simple implementation of a driver manager that differentiates between 14 * A simple implementation of a driver manager that differentiates between
17 * connected switches using the OF Description Statistics Reply message. 15 * connected switches using the OF Description Statistics Reply message.
18 */ 16 */
19 -public final class DriverManager { 17 +public final class DriverManager implements OpenFlowSwitchDriverFactory {
20 18
21 private static final Logger log = LoggerFactory.getLogger(DriverManager.class); 19 private static final Logger log = LoggerFactory.getLogger(DriverManager.class);
22 20
...@@ -32,7 +30,8 @@ public final class DriverManager { ...@@ -32,7 +30,8 @@ public final class DriverManager {
32 * @return A IOFSwitch instance if the driver found an implementation for 30 * @return A IOFSwitch instance if the driver found an implementation for
33 * the given description. Otherwise it returns OFSwitchImplBase 31 * the given description. Otherwise it returns OFSwitchImplBase
34 */ 32 */
35 - public static AbstractOpenFlowSwitch getOFSwitchImpl(Dpid dpid, 33 + @Override
34 + public OpenFlowSwitchDriver getOFSwitchImpl(Dpid dpid,
36 OFDescStatsReply desc, OFVersion ofv) { 35 OFDescStatsReply desc, OFVersion ofv) {
37 String vendor = desc.getMfrDesc(); 36 String vendor = desc.getMfrDesc();
38 String hw = desc.getHwDesc(); 37 String hw = desc.getHwDesc();
...@@ -53,42 +52,7 @@ public final class DriverManager { ...@@ -53,42 +52,7 @@ public final class DriverManager {
53 52
54 log.warn("DriverManager could not identify switch desc: {}. " 53 log.warn("DriverManager could not identify switch desc: {}. "
55 + "Assigning OFSwitchImplBase", desc); 54 + "Assigning OFSwitchImplBase", desc);
56 - AbstractOpenFlowSwitch base = new AbstractOpenFlowSwitch(dpid) { 55 + return null;
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 } 56 }
93 57
94 /** 58 /**
...@@ -108,4 +72,10 @@ public final class DriverManager { ...@@ -108,4 +72,10 @@ public final class DriverManager {
108 public static void setConfigForCpqd(boolean usePipeline13) { 72 public static void setConfigForCpqd(boolean usePipeline13) {
109 cpqdUsePipeline13 = usePipeline13; 73 cpqdUsePipeline13 = usePipeline13;
110 } 74 }
75 +
76 + public static OpenFlowSwitchDriver getSwitch(Dpid dpid,
77 + OFDescStatsReply desc, OFVersion ofv) {
78 + return new DriverManager().getOFSwitchImpl(dpid, desc, ofv);
79 + }
80 +
111 } 81 }
......
1 package org.onlab.onos.of.drivers; 1 package org.onlab.onos.of.drivers;
2 2
3 +import java.util.List;
4 +
3 import org.onlab.onos.of.controller.Dpid; 5 import org.onlab.onos.of.controller.Dpid;
4 -import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch; 6 +import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
5 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 7 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
6 import org.projectfloodlight.openflow.protocol.OFMessage; 8 import org.projectfloodlight.openflow.protocol.OFMessage;
7 9
...@@ -29,11 +31,6 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch { ...@@ -29,11 +31,6 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
29 } 31 }
30 32
31 @Override 33 @Override
32 - public void sendMsg(OFMessage m) {
33 - channel.write(m);
34 - }
35 -
36 - @Override
37 public Boolean supportNxRole() { 34 public Boolean supportNxRole() {
38 return true; 35 return true;
39 } 36 }
...@@ -48,4 +45,15 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch { ...@@ -48,4 +45,15 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
48 45
49 @Override 46 @Override
50 public void processDriverHandshakeMessage(OFMessage m) {} 47 public void processDriverHandshakeMessage(OFMessage m) {}
48 +
49 + @Override
50 + public void write(OFMessage msg) {
51 + channel.write(msg);
52 +
53 + }
54 +
55 + @Override
56 + public void write(List<OFMessage> msgs) {
57 + channel.write(msgs);
58 + }
51 } 59 }
......
1 package org.onlab.onos.of.drivers; 1 package org.onlab.onos.of.drivers;
2 2
3 +import java.util.List;
3 import java.util.concurrent.atomic.AtomicBoolean; 4 import java.util.concurrent.atomic.AtomicBoolean;
4 5
5 import org.onlab.onos.of.controller.Dpid; 6 import org.onlab.onos.of.controller.Dpid;
6 -import org.onlab.onos.of.controller.impl.internal.AbstractOpenFlowSwitch; 7 +import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
7 -import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeAlreadyStarted; 8 +import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
8 -import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeCompleted; 9 +import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeCompleted;
9 -import org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeNotStarted; 10 +import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeNotStarted;
10 import org.projectfloodlight.openflow.protocol.OFBarrierRequest; 11 import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
11 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 12 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
12 -import org.projectfloodlight.openflow.protocol.OFErrorMsg;
13 import org.projectfloodlight.openflow.protocol.OFFactory; 13 import org.projectfloodlight.openflow.protocol.OFFactory;
14 import org.projectfloodlight.openflow.protocol.OFMessage; 14 import org.projectfloodlight.openflow.protocol.OFMessage;
15 import org.slf4j.Logger; 15 import org.slf4j.Logger;
...@@ -25,7 +25,7 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch { ...@@ -25,7 +25,7 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
25 private static Logger log = 25 private static Logger log =
26 LoggerFactory.getLogger(OFSwitchImplOVS13.class); 26 LoggerFactory.getLogger(OFSwitchImplOVS13.class);
27 27
28 - private AtomicBoolean driverHandshakeComplete; 28 + private final AtomicBoolean driverHandshakeComplete;
29 private OFFactory factory; 29 private OFFactory factory;
30 private long barrierXidToWaitFor = -1; 30 private long barrierXidToWaitFor = -1;
31 31
...@@ -78,7 +78,7 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch { ...@@ -78,7 +78,7 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
78 break; 78 break;
79 79
80 case ERROR: 80 case ERROR:
81 - log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m); 81 + log.error("Switch {} Error {}", getStringId(), m);
82 break; 82 break;
83 83
84 case FEATURES_REPLY: 84 case FEATURES_REPLY:
...@@ -129,12 +129,18 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch { ...@@ -129,12 +129,18 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
129 } 129 }
130 130
131 @Override 131 @Override
132 - public void sendMsg(OFMessage m) { 132 + public Boolean supportNxRole() {
133 - channel.write(m); 133 + return false;
134 } 134 }
135 135
136 @Override 136 @Override
137 - public Boolean supportNxRole() { 137 + public void write(OFMessage msg) {
138 - return false; 138 + channel.write(msg);
139 +
140 + }
141 +
142 + @Override
143 + public void write(List<OFMessage> msgs) {
144 + channel.write(msgs);
139 } 145 }
140 } 146 }
......