@Override void processOFError(OFChannelHandler h, OFErrorMsg m) throws IOException, SwitchStateException { // if we get here, then the error message is for something else if (m.getErrType() == OFErrorType.BAD_REQUEST && ((OFBadRequestErrorMsg) m).getCode() == OFBadRequestCode.EPERM) { // We are the master controller and the switch returned // a permission error. This is a likely indicator that // the switch thinks we are slave. Reassert our // role // FIXME: this could be really bad during role transitions // if two controllers are master (even if its only for // a brief period). We might need to see if these errors // persist before we reassert h.sw.reassertRole(); } else if (m.getErrType() == OFErrorType.FLOW_MOD_FAILED && ((OFFlowModFailedErrorMsg) m).getCode() == OFFlowModFailedCode.ALL_TABLES_FULL) { h.sw.setTableFull(true); } else { logError(h, m); } h.dispatchMessage(m); }
@Override public void handleMessage(Dpid dpid, OFMessage msg) { switch (msg.getType()) { case STATS_REPLY: pushMeterStats(dpid, (OFStatsReply) msg); break; case ERROR: OFErrorMsg error = (OFErrorMsg) msg; if (error.getErrType() == OFErrorType.METER_MOD_FAILED) { MeterOperation op = pendingOperations.getIfPresent(error.getXid()); pendingOperations.invalidate(error.getXid()); if (op == null) { log.warn("Unknown Meter operation failed {}", error); } else { OFMeterModFailedErrorMsg meterError = (OFMeterModFailedErrorMsg) error; signalMeterError(meterError, op); } } break; default: break; } }
@Override void processOFError(OFErrorMsg m) { /* * HP ProCurve switches do not support * the ofpt_barrier_request message. * * Look for an error from a bad ofpt_barrier_request, * log a warning, but proceed. */ if (m.getErrType() == OFErrorType.BAD_REQUEST && ((OFBadRequestErrorMsg) m).getCode() == OFBadRequestCode.BAD_TYPE && ((OFBadRequestErrorMsg) m).getData().getParsedMessage().get() instanceof OFBarrierRequest) { log.warn("Switch does not support Barrier Request messages. Could be an HP ProCurve."); } else { logErrorDisconnect(m); } }
public boolean handleGenericDeliverable(OFMessage reply) { counters.updateReadStats(reply); @SuppressWarnings("unchecked") Deliverable<OFMessage> deliverable = (Deliverable<OFMessage>) this.xidDeliverableMap.get(reply.getXid()); if (deliverable != null) { if(reply instanceof OFErrorMsg) { deliverable.deliverError(new OFErrorMsgException((OFErrorMsg) reply)); } else { deliverable.deliver(reply); } if (deliverable.isDone()) this.xidDeliverableMap.remove(reply.getXid()); return true; } else { return false; } }
/** * Log an OpenFlow error message from a switch * @param error The error message */ @LogMessageDoc(level="ERROR", message="Error {error type} {error code} from {switch} " + "in state {state}", explanation="The switch responded with an unexpected error" + "to an OpenFlow message from the controller", recommendation="This could indicate improper network operation. " + "If the problem persists restarting the switch and " + "controller may help." ) protected void logError(OFErrorMsg error) { log.error("{} from switch {} in state {}", new Object[] { error.toString(), getSwitchInfoString(), this.toString()}); }
/** * Log an OpenFlow error message from a switch * @param sw The switch that sent the error * @param error The error message */ @LogMessageDoc(level="ERROR", message="Error {error type} {error code} from {switch} " + "in state {state}", explanation="The switch responded with an unexpected error" + "to an OpenFlow message from the controller", recommendation="This could indicate improper network operation. " + "If the problem persists restarting the switch and " + "controller may help." ) protected void logError(OFErrorMsg error) { log.error("{} from switch {} in state {}", new Object[] { error.toString(), getConnectionInfoString(), this.toString()}); }
/** * {@inheritDoc} */ @Override public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { logger.debug("OF_ERROR: {}", msg); // TODO: track xid for flow id if (OFType.ERROR.equals(msg.getType())) { ErrorMessage error = new ErrorMessage( new ErrorData(ErrorType.INTERNAL_ERROR, ((OFErrorMsg) msg).getErrType().toString(), null), System.currentTimeMillis(), DEFAULT_CORRELATION_ID, Destination.WFM_TRANSACTION); // TODO: Most/all commands are flow related, but not all. 'kilda.flow' might // not be the best place to send a generic error. kafkaProducer.postMessage("kilda.flow", error); } return Command.CONTINUE; }
@Override public boolean handleRoleError(OFErrorMsg error) { try { return RoleRecvStatus.OTHER_EXPECTATION != this.roleMan.deliverError(error); } catch (SwitchStateException e) { this.disconnectSwitch(); } return true; }
@Override void processOFMessage(OFChannelHandler h, OFMessage m) throws IOException, SwitchStateException { if (h.sw.isDriverHandshakeComplete()) { moveToActive(h); h.state.processOFMessage(h, m); return; } if (m.getType() == OFType.ECHO_REQUEST) { processOFEchoRequest(h, (OFEchoRequest) m); } else if (m.getType() == OFType.ECHO_REPLY) { processOFEchoReply(h, (OFEchoReply) m); } else if (m.getType() == OFType.ROLE_REPLY) { h.sw.handleRole(m); } else if (m.getType() == OFType.ERROR) { if (!h.sw.handleRoleError((OFErrorMsg)m)) { h.sw.processDriverHandshakeMessage(m); if (h.sw.isDriverHandshakeComplete()) { moveToActive(h); } } } else { if (m.getType() == OFType.EXPERIMENTER && ((OFExperimenter) m).getExperimenter() == RoleManager.NICIRA_EXPERIMENTER) { h.sw.handleNiciraRole(m); } else { h.sw.processDriverHandshakeMessage(m); if (h.sw.isDriverHandshakeComplete()) { moveToActive(h); } } } }
/** * Log an OpenFlow error message from a switch. * @param h The switch that sent the error * @param error The error message */ protected void logError(OFChannelHandler h, OFErrorMsg error) { log.error("{} from switch {} in state {}", error, h.getSwitchInfoString(), this.toString()); }
@Override public void handleMessage(Dpid dpid, OFMessage msg) { if (isDisabled) { return; } try { switch (msg.getType()) { case STATS_REPLY: if (((OFStatsReply) msg).getStatsType() == OFStatsType.PORT) { OFPortStatsReply portStatsReply = (OFPortStatsReply) msg; List<OFPortStatsEntry> portStatsReplyList = portStatsReplies.get(dpid); if (portStatsReplyList == null) { portStatsReplyList = Lists.newCopyOnWriteArrayList(); } portStatsReplyList.addAll(portStatsReply.getEntries()); portStatsReplies.put(dpid, portStatsReplyList); if (!portStatsReply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { List<OFPortStatsEntry> statsEntries = portStatsReplies.get(dpid); if (statsEntries != null) { pushPortMetrics(dpid, statsEntries); statsEntries.clear(); } } } break; case ERROR: if (((OFErrorMsg) msg).getErrType() == OFErrorType.PORT_MOD_FAILED) { LOG.error("port mod failed"); } default: break; } } catch (IllegalStateException e) { // system is shutting down and the providerService is no longer // valid. Messages cannot be processed. } }
/** * Log an OpenFlow error message from a switch * @param error The error message */ protected void logError(OFErrorMsg error) { log.error("{} from switch {} in state {}", new Object[] { error.toString(), getSwitchInfoString(), this.toString()}); }
/** * Process an OF message received on the channel and * update state accordingly. * * The main "event" of the state machine. Process the received message, * send follow up message if required and update state if required. * * Switches on the message type and calls more specific event handlers * for each individual OF message type. If we receive a message that * is supposed to be sent from a controller to a switch we throw * a SwitchStateExeption. * * The more specific handlers can also throw SwitchStateExceptions * * @param h The OFChannelHandler that received the message * @param m The message we received. * @throws SwitchStateException * @throws IOException */ void processOFMessage(OFMessage m) { roleChanger.checkTimeout(); switch(m.getType()) { case BARRIER_REPLY: processOFBarrierReply((OFBarrierReply) m); break; case ERROR: processOFError((OFErrorMsg) m); break; case FLOW_REMOVED: processOFFlowRemoved((OFFlowRemoved) m); break; case GET_CONFIG_REPLY: processOFGetConfigReply((OFGetConfigReply) m); break; case PACKET_IN: processOFPacketIn((OFPacketIn) m); break; case PORT_STATUS: processOFPortStatus((OFPortStatus) m); break; case QUEUE_GET_CONFIG_REPLY: processOFQueueGetConfigReply((OFQueueGetConfigReply) m); break; case STATS_REPLY: processOFStatsReply((OFStatsReply) m); break; case ROLE_REPLY: processOFRoleReply((OFRoleReply) m); break; case EXPERIMENTER: processOFExperimenter((OFExperimenter) m); break; default: illegalMessageReceived(m); break; } }
@Override void processOFError(OFErrorMsg m) { if ((m.getErrType() == OFErrorType.BAD_REQUEST) && ((((OFBadRequestErrorMsg)m).getCode() == OFBadRequestCode.MULTIPART_BUFFER_OVERFLOW) || ((OFBadRequestErrorMsg)m).getCode() == OFBadRequestCode.BAD_STAT)) { log.warn("Switch {} is {} but does not support OFTableFeaturesStats. Assuming all tables can perform any match, action, and instruction in the spec.", sw.getId().toString(), sw.getOFFactory().getVersion().toString()); } else { log.error("Received unexpected OFErrorMsg {} on switch {}.", m.toString(), sw.getId().toString()); } nextState(); }
@Override void processOFError(OFErrorMsg m) { // role changer will ignore the error if it isn't for it boolean didHandle = roleChanger.deliverError(m); if (!didHandle) { logError(m); } }
@Override void processOFError(OFErrorMsg m) { // role changer will ignore the error if it isn't for it boolean didHandle = roleChanger.deliverError(m); if (didHandle) return; if ((m.getErrType() == OFErrorType.BAD_REQUEST) && (((OFBadRequestErrorMsg)m).getCode() == OFBadRequestCode.EPERM)) { // We are the master controller and the switch returned // a permission error. This is a likely indicator that // the switch thinks we are slave. Reassert our // role // FIXME: this could be really bad during role transitions // if two controllers are master (even if its only for // a brief period). We might need to see if these errors // persist before we reassert switchManagerCounters.epermErrorWhileSwitchIsMaster.increment(); log.warn("Received permission error from switch {} while" + "being master. Reasserting master role.", getSwitchInfoString()); reassertRole(OFControllerRole.ROLE_MASTER); } else if ((m.getErrType() == OFErrorType.FLOW_MOD_FAILED) && (((OFFlowModFailedErrorMsg)m).getCode() == OFFlowModFailedCode.ALL_TABLES_FULL)) { sw.setTableFull(true); } else { logError(m); } dispatchMessage(m); }
/** * Log an OpenFlow error message from a switch * @param sw The switch that sent the error * @param error The error message */ protected void logError(OFErrorMsg error) { log.error("{} from switch {} in state {}", new Object[] { error.toString(), getConnectionInfoString(), this.toString()}); }
/** write a request which triggers an OFErrorMsg response */ @Test(timeout = 5000) public void testWriteRequestOFErrorMsg() throws InterruptedException, ExecutionException { Capture<List<OFMessage>> cMsgList = prepareChannelForWriteList(); OFRoleRequest roleRequest = factory.buildRoleRequest().setRole(OFControllerRole.ROLE_MASTER).build(); ListenableFuture<OFRoleReply> future = conn.writeRequest(roleRequest); assertThat("Connection should have 1 pending request", conn.getPendingRequestIds().size(), equalTo(1)); eventLoop.runTasks(); assertThat("Should have captured MsgList", cMsgList.getValue(), Matchers.<OFMessage> contains(roleRequest)); assertThat("Future should not be complete yet", future.isDone(), equalTo(false)); OFRoleRequestFailedErrorMsg roleError = factory.errorMsgs().buildRoleRequestFailedErrorMsg() .setXid(roleRequest.getXid()) .setCode(OFRoleRequestFailedCode.STALE) .build(); assertThat("Connection should have accepted the response", conn.deliverResponse(roleError), equalTo(true)); OFErrorMsgException e = FutureTestUtils.assertFutureFailedWithException(future, OFErrorMsgException.class); assertThat(e.getErrorMessage(), CoreMatchers.<OFErrorMsg>equalTo(roleError)); }
/** Return a bad request error message with the given xid/code */ private OFMessage getBadRequestErrorMessage(OFBadRequestCode code, long xid) { OFErrorMsg msg = factory.errorMsgs().buildBadRequestErrorMsg() .setXid(xid) .setCode(code) .build(); return msg; }
/** Return a bad action error message with the given xid/code */ private OFMessage getBadActionErrorMessage(OFBadActionCode code, long xid) { OFErrorMsg msg = factory.errorMsgs().buildBadActionErrorMsg() .setXid(xid) .setCode(code) .build(); return msg; }
@LogMessageDoc(level="WARN", message="Received permission error from switch {} while" + "being master. Reasserting master role.", explanation="The switch has denied an operation likely " + "indicating inconsistent controller roles", recommendation="This situation can occurs transiently during role" + " changes. If, however, the condition persists or happens" + " frequently this indicates a role inconsistency. " + LogMessageDoc.CHECK_CONTROLLER ) @Override void processOFError(OFErrorMsg m) { // role changer will ignore the error if it isn't for it boolean didHandle = roleChanger.deliverError(m); if (didHandle) return; if ((m.getErrType() == OFErrorType.BAD_REQUEST) && (((OFBadRequestErrorMsg)m).getCode() == OFBadRequestCode.EPERM)) { // We are the master controller and the switch returned // a permission error. This is a likely indicator that // the switch thinks we are slave. Reassert our // role // FIXME: this could be really bad during role transitions // if two controllers are master (even if its only for // a brief period). We might need to see if these errors // persist before we reassert switchManagerCounters.epermErrorWhileSwitchIsMaster.increment(); log.warn("Received permission error from switch {} while" + "being master. Reasserting master role.", getSwitchInfoString()); reassertRole(OFControllerRole.ROLE_MASTER); } else if ((m.getErrType() == OFErrorType.FLOW_MOD_FAILED) && (((OFFlowModFailedErrorMsg)m).getCode() == OFFlowModFailedCode.ALL_TABLES_FULL)) { sw.setTableFull(true); } else { logError(m); } dispatchMessage(m); }
/** write a request which triggers an OFErrorMsg response */ @Test(timeout = 5000) public void testWriteRequestOFErrorMsg() throws InterruptedException, ExecutionException { Capture<List<OFMessage>> cMsgList = prepareChannelForWriteList(); OFRoleRequest roleRequest = factory.buildRoleRequest().setRole(OFControllerRole.ROLE_MASTER).build(); ListenableFuture<OFRoleReply> future = conn.writeRequest(roleRequest); assertThat("Connection should have 1 pending request", conn.getPendingRequestIds().size(), equalTo(1)); assertThat("Should have captured MsgList", cMsgList.getValue(), Matchers.<OFMessage> contains(roleRequest)); assertThat("Future should not be complete yet", future.isDone(), equalTo(false)); OFRoleRequestFailedErrorMsg roleError = factory.errorMsgs().buildRoleRequestFailedErrorMsg() .setXid(roleRequest.getXid()) .setCode(OFRoleRequestFailedCode.STALE) .build(); assertThat("Connection should have accepted the response", conn.deliverResponse(roleError), equalTo(true)); OFErrorMsgException e = FutureTestUtils.assertFutureFailedWithException(future, OFErrorMsgException.class); assertThat(e.getErrorMessage(), CoreMatchers.<OFErrorMsg>equalTo(roleError)); }