RoleChanger bugs fixed:
1) Disconnect switch if no role-reply received from switch that supports role messages
2) Turn off pendingRole boolean when role-reply or error-msg is received
Change-Id: I4a5cfc5e99b85001192e5ac0e45202daac09bfa9
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java b/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
index a79e7d9..2008697 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
@@ -421,11 +421,11 @@
}
if (pendingRole == role) {
+ requestPending = false; // we got what we were waiting for
log.debug("Received role reply message from {} that matched "
+ "expected role-reply {} with expectations {}",
new Object[] {getSwitchInfoString(), role, expectation});
counters.roleReplyReceived.updateCounterWithFlush();
- //setSwitchRole(role, RoleRecvStatus.RECEIVED_REPLY); dont want to set state here
if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE ||
expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
return expectation;
@@ -435,9 +435,16 @@
}
// if xids match but role's don't, perhaps its a query (OF1.3)
- if (expectation == RoleRecvStatus.REPLY_QUERY)
+ if (expectation == RoleRecvStatus.REPLY_QUERY) {
+ requestPending = false; // again we got what we were waiting for
return expectation;
+ }
+ // It is not clear what this role-reply was about, since it is not
+ // a query and it did not match the pendingRole. But since the xid's
+ // matched, we state that we received what we were waiting for, and
+ // let the caller handle it
+ requestPending = false;
return RoleRecvStatus.OTHER_EXPECTATION;
}
@@ -467,6 +474,7 @@
return RoleRecvStatus.OTHER_EXPECTATION;
}
// it is an error related to a currently pending role request message
+ requestPending = false; // we got a response, even though it is an error
if (error.getErrType() == OFErrorType.BAD_REQUEST) {
counters.roleReplyErrorUnsupported.updateCounterWithFlush();
log.error("Received a error msg {} from sw {} in state {} for "
@@ -513,10 +521,13 @@
/**
* Check if a pending role request has timed out.
+ *
+ * @throws SwitchStateException
*/
- void checkTimeout() {
- if (!requestPending)
+ void checkTimeout() throws SwitchStateException {
+ if (!requestPending) {
return;
+ }
synchronized(this) {
if (!requestPending)
return;
@@ -524,8 +535,7 @@
if (now - roleSubmitTime > roleTimeoutMs) {
// timeout triggered.
counters.roleReplyTimeout.updateCounterWithFlush();
- //setSwitchRole(pendingRole, RoleRecvStatus.NO_REPLY);
- // XXX S come back to this
+ state.handleTimedOutRoleReply(OFChannelHandler.this, pendingRole);
}
}
}
@@ -1824,6 +1834,25 @@
RoleRecvStatus expectation) throws IOException {
// do nothing in most states
}
+
+ /**
+ * Handles role request messages that have timed out.
+ * <p>
+ * Role request messages that don't get role-replies (or errors related
+ * to the request) time out after DEFAULT_ROLE_TIMEOUT_MS secs, at which
+ * time the controller state-machine disconnects the switch
+ *
+ * @param h the channel handler for this switch
+ * @param pendingRole the role for which no reply was received
+ * @throws SwitchStateException
+ */
+ public void handleTimedOutRoleReply(OFChannelHandler h,
+ Role pendingRole) throws SwitchStateException {
+ String msg = String.format("Switch: [%s] State: [%s] did not "
+ + "reply to role-msg for pending role %s. Disconnecting ...",
+ h.getSwitchInfoString(), this.toString(), pendingRole);
+ throw new SwitchStateException(msg);
+ }
}