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