blob: 50e7b3317021ec8bf4fcef4ad821a30dcbce819c [file] [log] [blame]
alshabib54ebd9c2014-08-27 18:38:41 -07001package org.onlab.onos.of.controller.impl.internal;
2
3import java.io.IOException;
4import java.util.Collections;
alshabib54ebd9c2014-08-27 18:38:41 -07005
6import org.onlab.onos.of.controller.RoleState;
7import org.projectfloodlight.openflow.protocol.OFControllerRole;
8import org.projectfloodlight.openflow.protocol.OFErrorMsg;
9import org.projectfloodlight.openflow.protocol.OFErrorType;
10import org.projectfloodlight.openflow.protocol.OFExperimenter;
11import org.projectfloodlight.openflow.protocol.OFFactories;
12import org.projectfloodlight.openflow.protocol.OFMessage;
13import org.projectfloodlight.openflow.protocol.OFNiciraControllerRole;
14import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleReply;
15import org.projectfloodlight.openflow.protocol.OFRoleReply;
16import org.projectfloodlight.openflow.protocol.OFRoleRequest;
17import org.projectfloodlight.openflow.protocol.OFVersion;
18import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg;
19import org.projectfloodlight.openflow.protocol.errormsg.OFRoleRequestFailedErrorMsg;
20import org.projectfloodlight.openflow.types.U64;
21import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
24
25/**
26 * A utility class to handle role requests and replies for this channel.
27 * After a role request is submitted the role changer keeps track of the
28 * pending request, collects the reply (if any) and times out the request
29 * if necessary.
30 *
31 * To simplify role handling we only keep track of the /last/ pending
32 * role reply send to the switch. If multiple requests are pending and
33 * we receive replies for earlier requests we ignore them. However, this
34 * way of handling pending requests implies that we could wait forever if
35 * a new request is submitted before the timeout triggers. If necessary
36 * we could work around that though.
37 */
38class RoleManager {
39 protected static final long NICIRA_EXPERIMENTER = 0x2320;
40
41 private static Logger log = LoggerFactory.getLogger(RoleManager.class);
42 // indicates that a request is currently pending
43 // needs to be volatile to allow correct double-check idiom
44 private volatile boolean requestPending;
45 // the transaction Id of the pending request
46 private int pendingXid;
47 // the role that's pending
48 private RoleState pendingRole;
49
50 // the expectation set by the caller for the returned role
51 private RoleRecvStatus expectation;
alshabib54ebd9c2014-08-27 18:38:41 -070052 private AbstractOpenFlowSwitch sw;
53
54
55 public RoleManager(AbstractOpenFlowSwitch sw) {
56 this.requestPending = false;
57 this.pendingXid = -1;
58 this.pendingRole = null;
alshabib54ebd9c2014-08-27 18:38:41 -070059 this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE;
60 this.sw = sw;
61 }
62
63 /**
64 * Send NX role request message to the switch requesting the specified
65 * role.
66 *
67 * @param sw switch to send the role request message to
68 * @param role role to request
69 */
70 private int sendNxRoleRequest(RoleState role) throws IOException {
71 // Convert the role enum to the appropriate role to send
72 OFNiciraControllerRole roleToSend = OFNiciraControllerRole.ROLE_OTHER;
73 switch (role) {
74 case MASTER:
75 roleToSend = OFNiciraControllerRole.ROLE_MASTER;
76 break;
77 case SLAVE:
78 case EQUAL:
79 default:
80 // ensuring that the only two roles sent to 1.0 switches with
81 // Nicira role support, are MASTER and SLAVE
82 roleToSend = OFNiciraControllerRole.ROLE_SLAVE;
83 log.warn("Sending Nx Role.SLAVE to switch {}.", sw);
84 }
alshabibd777b202014-08-28 17:52:55 -070085 int xid = sw.getNextTransactionId();
alshabib54ebd9c2014-08-27 18:38:41 -070086 OFExperimenter roleRequest = OFFactories.getFactory(OFVersion.OF_10)
87 .buildNiciraControllerRoleRequest()
88 .setXid(xid)
89 .setRole(roleToSend)
90 .build();
91 sw.write(Collections.<OFMessage>singletonList(roleRequest));
92 return xid;
93 }
94
95 private int sendOF13RoleRequest(RoleState role) throws IOException {
96 // Convert the role enum to the appropriate role to send
97 OFControllerRole roleToSend = OFControllerRole.ROLE_NOCHANGE;
98 switch (role) {
99 case EQUAL:
100 roleToSend = OFControllerRole.ROLE_EQUAL;
101 break;
102 case MASTER:
103 roleToSend = OFControllerRole.ROLE_MASTER;
104 break;
105 case SLAVE:
106 roleToSend = OFControllerRole.ROLE_SLAVE;
107 break;
108 default:
109 log.warn("Sending default role.noChange to switch {}."
110 + " Should only be used for queries.", sw);
111 }
112
alshabibd777b202014-08-28 17:52:55 -0700113 int xid = sw.getNextTransactionId();
alshabib54ebd9c2014-08-27 18:38:41 -0700114 OFRoleRequest rrm = OFFactories.getFactory(OFVersion.OF_13)
115 .buildRoleRequest()
116 .setRole(roleToSend)
117 .setXid(xid)
118 //FIXME fix below when we actually use generation ids
119 .setGenerationId(U64.ZERO)
120 .build();
alshabibd777b202014-08-28 17:52:55 -0700121 sw.sendMsg(rrm);
alshabib54ebd9c2014-08-27 18:38:41 -0700122 return xid;
123 }
124
125 /**
126 * Send a role request with the given role to the switch and update
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 {
147 this.expectation = exp;
148
149 if (sw.factory().getVersion() == OFVersion.OF_10) {
150 Boolean supportsNxRole = (Boolean)
151 sw.supportNxRole();
152 if (!supportsNxRole) {
153 log.debug("Switch driver indicates no support for Nicira "
154 + "role request messages. Not sending ...");
155 handleUnsentRoleMessage(role,
156 expectation);
157 return false;
158 }
159 // OF1.0 switch with support for NX_ROLE_REQUEST vendor extn.
160 // make Role.EQUAL become Role.SLAVE
161 role = (role == RoleState.EQUAL) ? RoleState.SLAVE : role;
162 pendingXid = sendNxRoleRequest(role);
163 pendingRole = role;
164 requestPending = true;
165 } else {
166 // OF1.3 switch, use OFPT_ROLE_REQUEST message
167 pendingXid = sendOF13RoleRequest(role);
168 pendingRole = role;
169 requestPending = true;
170 }
171 return true;
172 }
173
174 private void handleUnsentRoleMessage(RoleState role,
175 RoleRecvStatus exp) throws IOException {
176 // typically this is triggered for a switch where role messages
177 // are not supported - we confirm that the role being set is
178 // master
179 if (exp != RoleRecvStatus.MATCHED_SET_ROLE) {
180
181 log.error("Expected MASTER role from registry for switch "
182 + "which has no support for role-messages."
183 + "Received {}. It is possible that this switch "
184 + "is connected to other controllers, in which "
185 + "case it should support role messages - not "
186 + "moving forward.", role);
187
188 }
189
190 }
191
192 /**
193 * Deliver a received role reply.
194 *
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 {
210 if (!requestPending) {
211 RoleState currentRole = (sw != null) ? sw.getRole() : null;
212 if (currentRole != null) {
213 if (currentRole == rri.getRole()) {
214 // Don't disconnect if the role reply we received is
215 // for the same role we are already in.
216 log.debug("Received unexpected RoleReply from "
217 + "Switch: {}. "
218 + "Role in reply is same as current role of this "
219 + "controller for this sw. Ignoring ...",
220 sw.getStringId());
221 return RoleRecvStatus.OTHER_EXPECTATION;
222 } else {
223 String msg = String.format("Switch: [%s], "
224 + "received unexpected RoleReply[%s]. "
225 + "No roles are pending, and this controller's "
226 + "current role:[%s] does not match reply. "
227 + "Disconnecting switch ... ",
228 sw.getStringId(),
229 rri, currentRole);
230 throw new SwitchStateException(msg);
231 }
232 }
233 log.debug("Received unexpected RoleReply {} from "
234 + "Switch: {}. "
235 + "This controller has no current role for this sw. "
236 + "Ignoring ...", new Object[] {rri,
237 sw.getStringId(), });
238 return RoleRecvStatus.OTHER_EXPECTATION;
239 }
240
241 int xid = (int) rri.getXid();
242 RoleState role = rri.getRole();
243 // XXX S should check generation id meaningfully and other cases of expectations
244 // U64 genId = rri.getGenId();
245
246 if (pendingXid != xid) {
247 log.debug("Received older role reply from " +
248 "switch {} ({}). Ignoring. " +
249 "Waiting for {}, xid={}",
250 new Object[] {sw.getStringId(), rri,
251 pendingRole, pendingXid });
252 return RoleRecvStatus.OLD_REPLY;
253 }
254
255 if (pendingRole == role) {
256 log.debug("Received role reply message from {} that matched "
257 + "expected role-reply {} with expectations {}",
258 new Object[] {sw.getStringId(), role, expectation});
259
260 //setSwitchRole(role, RoleRecvStatus.RECEIVED_REPLY); dont want to set state here
261 if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE ||
262 expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
263 return expectation;
264 } else {
265 return RoleRecvStatus.OTHER_EXPECTATION;
266 }
267 }
268
269 // if xids match but role's don't, perhaps its a query (OF1.3)
270 if (expectation == RoleRecvStatus.REPLY_QUERY) {
271 return expectation;
272 }
273
274 return RoleRecvStatus.OTHER_EXPECTATION;
275 }
276
277 /**
278 * Called if we receive an error message. If the xid matches the
279 * pending request we handle it otherwise we ignore it.
280 *
281 * Note: since we only keep the last pending request we might get
282 * error messages for earlier role requests that we won't be able
283 * to handle
284 */
285 synchronized RoleRecvStatus deliverError(OFErrorMsg error)
286 throws SwitchStateException {
287 if (!requestPending) {
288 log.debug("Received an error msg from sw {}, but no pending "
289 + "requests in role-changer; not handling ...",
290 sw.getStringId());
291 return RoleRecvStatus.OTHER_EXPECTATION;
292 }
293 if (pendingXid != error.getXid()) {
294 if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
295 log.debug("Received an error msg from sw {} for a role request,"
296 + " but not for pending request in role-changer; "
297 + " ignoring error {} ...",
298 sw.getStringId(), error);
299 }
300 return RoleRecvStatus.OTHER_EXPECTATION;
301 }
302 // it is an error related to a currently pending role request message
303 if (error.getErrType() == OFErrorType.BAD_REQUEST) {
304 log.error("Received a error msg {} from sw {} for "
305 + "pending role request {}. Switch driver indicates "
306 + "role-messaging is supported. Possible issues in "
307 + "switch driver configuration?", new Object[] {
308 ((OFBadRequestErrorMsg) error).toString(),
309 sw.getStringId(), pendingRole
310 });
311 return RoleRecvStatus.UNSUPPORTED;
312 }
313
314 if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
315 OFRoleRequestFailedErrorMsg rrerr =
316 (OFRoleRequestFailedErrorMsg) error;
317 switch (rrerr.getCode()) {
318 case BAD_ROLE:
319 // switch says that current-role-req has bad role?
320 // for now we disconnect
321 // fall-thru
322 case STALE:
323 // switch says that current-role-req has stale gen-id?
324 // for now we disconnect
325 // fall-thru
326 case UNSUP:
327 // switch says that current-role-req has role that
328 // cannot be supported? for now we disconnect
329 String msgx = String.format("Switch: [%s], "
330 + "received Error to for pending role request [%s]. "
331 + "Error:[%s]. Disconnecting switch ... ",
332 sw.getStringId(),
333 pendingRole, rrerr);
334 throw new SwitchStateException(msgx);
335 default:
336 break;
337 }
338 }
339
340 // This error message was for a role request message but we dont know
341 // how to handle errors for nicira role request messages
342 return RoleRecvStatus.OTHER_EXPECTATION;
343 }
344
345 /**
346 * Extract the role from an OFVendor message.
347 *
348 * Extract the role from an OFVendor message if the message is a
349 * Nicira role reply. Otherwise return null.
350 *
351 * @param h The channel handler receiving the message
352 * @param vendorMessage The vendor message to parse.
353 * @return The role in the message if the message is a Nicira role
354 * reply, null otherwise.
355 * @throws SwitchStateException If the message is a Nicira role reply
356 * but the numeric role value is unknown.
357 */
358 protected RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg)
359 throws SwitchStateException {
360 int vendor = (int) experimenterMsg.getExperimenter();
361 if (vendor != 0x2320) {
362 return null;
363 }
364 OFNiciraControllerRoleReply nrr =
365 (OFNiciraControllerRoleReply) experimenterMsg;
366
367 RoleState role = null;
368 OFNiciraControllerRole ncr = nrr.getRole();
369 switch(ncr) {
370 case ROLE_MASTER:
371 role = RoleState.MASTER;
372 break;
373 case ROLE_OTHER:
374 role = RoleState.EQUAL;
375 break;
376 case ROLE_SLAVE:
377 role = RoleState.SLAVE;
378 break;
379 default: //handled below
380 }
381
382 if (role == null) {
383 String msg = String.format("Switch: [%s], "
384 + "received NX_ROLE_REPLY with invalid role "
385 + "value %s",
386 sw.getStringId(),
387 nrr.getRole());
388 throw new SwitchStateException(msg);
389 }
390 return role;
391 }
392
393 /**
394 * When we remove a pending role request we use this enum to indicate how we
395 * arrived at the decision. When we send a role request to the switch, we
396 * also use this enum to indicate what we expect back from the switch, so the
397 * role changer can match the reply to our expectation.
398 */
399 public enum RoleRecvStatus {
400 /** The switch returned an error indicating that roles are not.
401 * supported*/
402 UNSUPPORTED,
403 /** The request timed out. */
404 NO_REPLY,
405 /** The reply was old, there is a newer request pending. */
406 OLD_REPLY,
407 /**
408 * The reply's role matched the role that this controller set in the
409 * request message - invoked either initially at startup or to reassert
410 * current role.
411 */
412 MATCHED_CURRENT_ROLE,
413 /**
414 * The reply's role matched the role that this controller set in the
415 * request message - this is the result of a callback from the
416 * global registry, followed by a role request sent to the switch.
417 */
418 MATCHED_SET_ROLE,
419 /**
420 * The reply's role was a response to the query made by this controller.
421 */
422 REPLY_QUERY,
423 /** We received a role reply message from the switch
424 * but the expectation was unclear, or there was no expectation.
425 */
426 OTHER_EXPECTATION,
427 }
428
429 /**
430 * Helper class returns role reply information in the format understood
431 * by the controller.
432 */
433 protected static class RoleReplyInfo {
434 private RoleState role;
435 private U64 genId;
436 private long xid;
437
438 RoleReplyInfo(RoleState role, U64 genId, long xid) {
439 this.role = role;
440 this.genId = genId;
441 this.xid = xid;
442 }
443 public RoleState getRole() { return role; }
444 public U64 getGenId() { return genId; }
445 public long getXid() { return xid; }
446 @Override
447 public String toString() {
448 return "[Role:" + role + " GenId:" + genId + " Xid:" + xid + "]";
449 }
450 }
451
452 /**
453 * Extract the role information from an OF1.3 Role Reply Message.
454 * @param h
455 * @param rrmsg
456 * @return RoleReplyInfo object
457 * @throws SwitchStateException
458 */
459 protected RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg)
460 throws SwitchStateException {
461 OFControllerRole cr = rrmsg.getRole();
462 RoleState role = null;
463 switch(cr) {
464 case ROLE_EQUAL:
465 role = RoleState.EQUAL;
466 break;
467 case ROLE_MASTER:
468 role = RoleState.MASTER;
469 break;
470 case ROLE_SLAVE:
471 role = RoleState.SLAVE;
472 break;
473 case ROLE_NOCHANGE: // switch should send current role
474 default:
475 String msg = String.format("Unknown controller role %s "
476 + "received from switch %s", cr, sw);
477 throw new SwitchStateException(msg);
478 }
479
480 return new RoleReplyInfo(role, rrmsg.getGenerationId(), rrmsg.getXid());
481 }
482
483}
484
485
486///**
487// * We are waiting for a role reply message in response to a role request
488// * sent after hearing back from the registry service -- OR -- we are
489// * just waiting to hear back from the registry service in the case that
490// * the switch does not support role messages. If completed successfully,
491// * the controller's role for this switch will be set here.
492// * Before we move to the state corresponding to the role, we allow the
493// * switch specific driver to complete its configuration. This configuration
494// * typically depends on the role the controller is playing for this switch.
495// * And so we set the switch role (for 'this' controller) before we start
496// * the driver-sub-handshake.
497// * Next State: WAIT_SWITCH_DRIVER_SUB_HANDSHAKE
498// */
499//WAIT_INITIAL_ROLE(false) {
500// @Override
501// void processOFError(OFChannelHandler h, OFErrorMsg m)
502// throws SwitchStateException {
503// // role changer will ignore the error if it isn't for it
504// RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
505// if (rrstatus == RoleRecvStatus.OTHER_EXPECTATION) {
506// logError(h, m);
507// }
508// }
509//
510// @Override
511// void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
512// throws IOException, SwitchStateException {
513// Role role = extractNiciraRoleReply(h, m);
514// // If role == null it means the vendor (experimenter) message
515// // wasn't really a Nicira role reply. We ignore this case.
516// if (role != null) {
517// RoleReplyInfo rri = new RoleReplyInfo(role, null, m.getXid());
518// RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
519// if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
520// setRoleAndStartDriverHandshake(h, rri.getRole());
521// } // else do nothing - wait for the correct expected reply
522// } else {
523// unhandledMessageReceived(h, m);
524// }
525// }
526//
527// @Override
528// void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
529// throws SwitchStateException, IOException {
530// RoleReplyInfo rri = extractOFRoleReply(h, m);
531// RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
532// if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
533// setRoleAndStartDriverHandshake(h, rri.getRole());
534// } // else do nothing - wait for the correct expected reply
535// }
536//
537// @Override
538// void handleUnsentRoleMessage(OFChannelHandler h, Role role,
539// RoleRecvStatus expectation) throws IOException {
540// // typically this is triggered for a switch where role messages
541// // are not supported - we confirm that the role being set is
542// // master and move to the next state
543// if (expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
544// if (role == Role.MASTER) {
545// setRoleAndStartDriverHandshake(h, role);
546// } else {
547// log.error("Expected MASTER role from registry for switch "
548// + "which has no support for role-messages."
549// + "Received {}. It is possible that this switch "
550// + "is connected to other controllers, in which "
551// + "case it should support role messages - not "
552// + "moving forward.", role);
553// }
554// } // else do nothing - wait to hear back from registry
555//
556// }
557//
558// private void setRoleAndStartDriverHandshake(OFChannelHandler h,
559// Role role) throws IOException {
560// h.setSwitchRole(role);
561// h.sw.startDriverHandshake();
562// if (h.sw.isDriverHandshakeComplete()) {
563// Role mySwitchRole = h.sw.getRole();
564// if (mySwitchRole == Role.MASTER) {
565// log.info("Switch-driver sub-handshake complete. "
566// + "Activating switch {} with Role: MASTER",
567// h.sw.getStringId());
568// handlePendingPortStatusMessages(h); //before activation
569// boolean success = h.sw.addActivatedMasterSwitch();
570// if (!success) {
571// disconnectDuplicate(h);
572// return;
573// }
574// h.setState(MASTER);
575// } else {
576// log.info("Switch-driver sub-handshake complete. "
577// + "Activating switch {} with Role: EQUAL",
578// h.sw.getStringId());
579// handlePendingPortStatusMessages(h); //before activation
580// boolean success = h.sw.addActivatedEqualSwitch();
581// if (!success) {
582// disconnectDuplicate(h);
583// return;
584// }
585// h.setState(EQUAL);
586// }
587// } else {
588// h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
589// }
590// }
591//
592// @Override
593// void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m)
594// throws IOException, SwitchStateException {
595// illegalMessageReceived(h, m);
596// }
597//
598// @Override
599// void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m)
600// throws SwitchStateException {
601// illegalMessageReceived(h, m);
602// }
603//
604// @Override
605// void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
606// throws IOException, SwitchStateException {
607// h.pendingPortStatusMsg.add(m);
608//
609// }
610//},
611
612
613
614
615
616
617
618///**
619// * This controller is in EQUAL role for this switch. We enter this state
620// * after some /other/ controller instance wins mastership-role over this
621// * switch. The EQUAL role can be considered the same as the SLAVE role
622// * if this controller does NOT send commands or packets to the switch.
623// * This should always be true for OF1.0 switches. XXX S need to enforce.
624// *
625// * For OF1.3 switches, choosing this state as EQUAL instead of SLAVE,
626// * gives us the flexibility that if an app wants to send commands/packets
627// * to switches, it can, even thought it is running on a controller instance
628// * that is not in a MASTER role for this switch. Of course, it is the job
629// * of the app to ensure that commands/packets sent by this (EQUAL) controller
630// * instance does not clash/conflict with commands/packets sent by the MASTER
631// * controller for this switch. Neither the controller instances, nor the
632// * switch provides any kind of resolution mechanism should conflicts occur.
633// */
634//EQUAL(true) {
635// @Override
636// void processOFError(OFChannelHandler h, OFErrorMsg m)
637// throws IOException, SwitchStateException {
638// // role changer will ignore the error if it isn't for it
639// RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
640// if (rrstatus == RoleRecvStatus.OTHER_EXPECTATION) {
641// logError(h, m);
642// h.dispatchMessage(m);
643// }
644// }
645//
646// @Override
647// void processOFStatisticsReply(OFChannelHandler h,
648// OFStatsReply m) {
649// h.sw.handleMessage(m);
650// }
651//
652// @Override
653// void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
654// throws IOException, SwitchStateException {
655// Role role = extractNiciraRoleReply(h, m);
656// // If role == null it means the message wasn't really a
657// // Nicira role reply. We ignore it in this state.
658// if (role != null) {
659// RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(
660// new RoleReplyInfo(role, null, m.getXid()));
661// if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
662// checkAndSetRoleTransition(h, role);
663// }
664// } else {
665// unhandledMessageReceived(h, m);
666// }
667// }
668//
669// @Override
670// void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
671// throws SwitchStateException, IOException {
672// RoleReplyInfo rri = extractOFRoleReply(h, m);
673// RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
674// if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
675// checkAndSetRoleTransition(h, rri.getRole());
676// }
677// }
678//
679// // XXX S needs more handlers for 1.3 switches in equal role
680//
681// @Override
682// void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
683// throws IOException, SwitchStateException {
684// handlePortStatusMessage(h, m, true);
685// }
686//
687// @Override
688// @LogMessageDoc(level = "WARN",
689// message = "Received PacketIn from switch {} while "
690// + "being slave. Reasserting slave role.",
691// explanation = "The switch has receive a PacketIn despite being "
692// + "in slave role indicating inconsistent controller roles",
693// recommendation = "This situation can occurs transiently during role"
694// + " changes. If, however, the condition persists or happens"
695// + " frequently this indicates a role inconsistency. "
696// + LogMessageDoc.CHECK_CONTROLLER)
697// void processOFPacketIn(OFChannelHandler h, OFPacketIn m) throws IOException {
698// // we don't expect packetIn while slave, reassert we are slave
699// h.counters.packetInWhileSwitchIsSlave.updateCounterNoFlush();
700// log.warn("Received PacketIn from switch {} while" +
701// "being slave. Reasserting slave role.", h.sw);
702// //h.controller.reassertRole(h, Role.SLAVE);
703// // XXX reassert in role changer
704// }
705//};