@LogMessageDocs({ @LogMessageDoc(message="Controller role set to {role}", explanation="Setting the initial HA role to "), @LogMessageDoc(level="ERROR", message="Invalid current role value: {role}", explanation="An invalid HA role value was read from the " + "properties file", recommendation=LogMessageDoc.CHECK_CONTROLLER) }) protected HARole getInitialRole(Map<String, String> configParams) { HARole role = HARole.STANDBY; String roleString = configParams.get("role"); if (roleString != null) { try { role = HARole.valueOfBackwardsCompatible(roleString); } catch (IllegalArgumentException exc) { log.error("Invalid current role value: {}", roleString); } } log.info("Controller role set to {}", role); return role; }
@Override @LogMessageDocs({ @LogMessageDoc(level="WARN", message="Error parsing flow idle timeout, " + "using default of {number} seconds", explanation="The properties file contains an invalid " + "flow idle timeout", recommendation="Correct the idle timeout in the " + "properties file."), @LogMessageDoc(level="WARN", message="Error parsing flow hard timeout, " + "using default of {number} seconds", explanation="The properties file contains an invalid " + "flow hard timeout", recommendation="Correct the hard timeout in the " + "properties file.") }) public void init(FloodlightModuleContext context) throws FloodlightModuleException { super.init(); this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); this.deviceManager = context.getServiceImpl(IDeviceService.class); this.routingEngine = context.getServiceImpl(IRoutingService.class); this.topology = context.getServiceImpl(ITopologyService.class); this.counterStore = context.getServiceImpl(ICounterStoreService.class); }
@LogMessageDocs({ @LogMessageDoc(level="WARN", message="Failed to cleanly shut down RPC server", explanation="Could not close all open sockets cleanly"), @LogMessageDoc(level="WARN", message="Interrupted while shutting down RPC server", explanation="Could not close all open sockets cleanly") }) public void shutdown() { shutDown = true; try { if (!cg.close().await(5, TimeUnit.SECONDS)) { logger.warn("Failed to cleanly shut down RPC server"); return; } if (clientBootstrap != null) clientBootstrap.releaseExternalResources(); clientBootstrap = null; if (serverBootstrap != null) serverBootstrap.releaseExternalResources(); serverBootstrap = null; if (pipelineFactory != null) pipelineFactory.releaseExternalResources(); pipelineFactory = null; if (bossExecutor != null) bossExecutor.shutdown(); bossExecutor = null; if (workerExecutor != null) workerExecutor.shutdown(); workerExecutor = null; } catch (InterruptedException e) { logger.warn("Interrupted while shutting down RPC server"); } logger.debug("Internal floodlight RPC shut down"); }
@Override @LogMessageDocs({ @LogMessageDoc(level="WARN", message="Config Reply from {switch} has " + "miss length set to {length}", explanation="The controller requires that the switch " + "use a miss length of 0xffff for correct " + "function", recommendation="Use a different switch to ensure " + "correct function") }) void processOFGetConfigReply(OFGetConfigReply m) { if (m.getMissSendLen() == 0xffff) { log.trace("Config Reply from switch {} confirms " + "miss length set to 0xffff", getSwitchInfoString()); } else { // FIXME: we can't really deal with switches that don't send // full packets. Shouldn't we drop the connection here? // FIXME: count?? log.warn("Config Reply from switch {} has" + "miss length set to {}", getSwitchInfoString(), m.getMissSendLen()); } setState(new WaitDescriptionStatReplyState()); }
@Override @LogMessageDocs({ @LogMessageDoc(level="WARN", message="Drop throttled OF message to switch {switch}", explanation="The controller is sending more messages" + "than the switch can handle. Some messages are dropped" + "to prevent switch outage", recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG) }) public void writeThrottled(OFMessage m, FloodlightContext bc) throws IOException { if (channel == null || !isConnected()) return; /** * By default, channel uses an unbounded send queue. Enable throttling * prevents the queue from growing big. * * channel.isWritable() returns true when queue length is less than * high water mark (64 kbytes). Once exceeded, isWritable() becomes * false after queue length drops below low water mark (32 kbytes). */ if (!writeThrottleEnabled || channel.isWritable()) { write(m, bc); } else { // Let logback duplicate filtering take care of excessive logs ctrSwitchWriteDrops.updateCounterNoFlush(); log.warn("Drop throttled OF message to switch {}", this); } }
@LogMessageDocs({ @LogMessageDoc(level="INFO", message="Switch {switch} flow table is full", explanation="The switch flow table at least 98% full, " + "this requires attention if using reactive flow setup"), @LogMessageDoc(level="INFO", message="Switch {switch} flow table capacity back to normal", explanation="The switch flow table is less than 90% full") }) private void checkForTableStats(OFStatisticsReply statReply) { if (statReply.getStatisticType() != OFStatisticsType.TABLE) { return; } List<? extends OFStatistics> stats = statReply.getStatistics(); // Assume a single table only OFStatistics stat = stats.get(0); if (stat instanceof OFTableStatistics) { OFTableStatistics tableStat = (OFTableStatistics) stat; int activeCount = tableStat.getActiveCount(); int maxEntry = tableStat.getMaximumEntries(); log.debug("Switch {} active entries {} max entries {}", new Object[] { this.stringId, activeCount, maxEntry}); int percentFull = activeCount * 100 / maxEntry; if (flowTableFull && percentFull < 90) { log.info("Switch {} flow table capacity is back to normal", toString()); floodlightProvider.addSwitchEvent(this.datapathId, "SWITCH_FLOW_TABLE_NORMAL < 90% full", false); } else if (percentFull >= 98) { log.info("Switch {} flow table is almost full", toString()); floodlightProvider.addSwitchEvent(this.datapathId, "SWITCH_FLOW_TABLE_ALMOST_FULL >= 98% full", false); } } }
/** * Loads the modules from a specified configuration file. * @param fName The configuration file path * @return An IFloodlightModuleContext with all the modules to be started * @throws FloodlightModuleException */ @LogMessageDocs({ @LogMessageDoc(level="INFO", message="Loading modules from file {file name}", explanation="The controller is initializing its module " + "configuration from the specified properties file"), @LogMessageDoc(level="INFO", message="Loading default modules", explanation="The controller is initializing its module " + "configuration to the default configuration"), @LogMessageDoc(level="ERROR", message="Could not load module configuration file", explanation="The controller failed to read the " + "module configuration file", recommendation="Verify that the module configuration is " + "present. " + LogMessageDoc.CHECK_CONTROLLER), @LogMessageDoc(level="ERROR", message="Could not load default modules", explanation="The controller failed to read the default " + "module configuration", recommendation=LogMessageDoc.CHECK_CONTROLLER) }) public IFloodlightModuleContext loadModulesFromConfig(String fName) throws FloodlightModuleException { Properties prop = new Properties(); Collection<String> configMods; File f = new File(fName); if (f.isFile()) { logger.info("Loading modules from file {}", f.getPath()); configMods = loadProperties(null, f, prop); } else { logger.info("Loading default modules"); InputStream is = this.getClass().getClassLoader(). getResourceAsStream(COMPILED_CONF_FILE); configMods = loadProperties(is, null, prop); } return loadModulesFromList(configMods, prop); }
@Override @LogMessageDocs({ @LogMessageDoc(level="ERROR", message="Error reinjecting OFMessage on switch {switch}", explanation="An I/O error occured while attempting to " + "process an OpenFlow message", recommendation=LogMessageDoc.CHECK_SWITCH) }) public boolean injectOfMessage(IOFSwitch sw, OFMessage msg, FloodlightContext bc) { if (sw == null) throw new NullPointerException("Switch must not be null"); if (msg == null) throw new NullPointerException("OFMessage must not be null"); // FIXME: Do we need to be able to inject messages from switches // where we're the slave controller (i.e. they're connected but // not active)? if (!sw.isActive()) return false; try { // Pass Floodlight context to the handleMessages() handleMessage(sw, msg, bc); } catch (IOException e) { log.error("Error reinjecting OFMessage on switch {}", sw.getStringId()); return false; } return true; }
@Override @LogMessageDocs({ @LogMessageDoc(level="WARN", message="Config Reply from {switch} has " + "miss length set to {length}", explanation="The controller requires that the switch " + "use a miss length of 0xffff for correct " + "function", recommendation="Use a different switch to ensure " + "correct function") }) void processOFGetConfigReply(OFChannelHandler h, OFGetConfigReply m) throws IOException { if (m.getMissSendLength() == (short)0xffff) { log.trace("Config Reply from switch {} confirms " + "miss length set to 0xffff", h.getSwitchInfoString()); } else { // FIXME: we can't really deal with switches that don't send // full packets. Shouldn't we drop the connection here? // FIXME: count?? log.warn("Config Reply from switch {} has" + "miss length set to {}", h.getSwitchInfoString(), m.getMissSendLength()); } h.sendHandshakeDescriptionStatsRequest(); h.setState(WAIT_DESCRIPTION_STAT_REPLY); }
@Override @LogMessageDocs({ @LogMessageDoc(message="Failed to inject OFMessage {message} onto " + "a null switch", explanation="Failed to process a message because the switch " + " is no longer connected."), @LogMessageDoc(level="ERROR", message="Error reinjecting OFMessage on switch {switch}", explanation="An I/O error occured while attempting to " + "process an OpenFlow message", recommendation=LogMessageDoc.CHECK_SWITCH) }) public boolean injectOfMessage(IOFSwitch sw, OFMessage msg, FloodlightContext bc) { if (sw == null) { log.info("Failed to inject OFMessage {} onto a null switch", msg); return false; } // FIXME: Do we need to be able to inject messages to switches // where we're the slave controller (i.e. they're connected but // not active)? // FIXME: Don't we need synchronization logic here so we're holding // the listener read lock when we call handleMessage? After some // discussions it sounds like the right thing to do here would be to // inject the message as a netty upstream channel event so it goes // through the normal netty event processing, including being // handled if (!activeSwitches.containsKey(sw.getId())) return false; try { // Pass Floodlight context to the handleMessages() handleMessage(sw, msg, bc); } catch (IOException e) { log.error("Error reinjecting OFMessage on switch {}", HexString.toHexString(sw.getId())); return false; } return true; }