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 | } | ... | ... |
... | @@ -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 | +} |
of/api/src/main/java/org/onlab/onos/of/controller/driver/OpenFlowSwitchDriverFactory.java
0 → 100644
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 | +} |
... | @@ -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 | } | ... | ... |
This diff is collapsed. Click to expand it.
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 | } | ... | ... |
-
Please register or login to post a comment